2012-08-24 20 views
5

tengo el siguiente código C# para encontrar a los niños de un DepedendencyObject:VisualTreeHelper.GetChildren no encuentra los niños de TabItem

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject parent) where T : DependencyObject 
    { 
     int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < childrenCount; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parent, i); 

      T childType = child as T; 
      if (childType == null) 
      { 
       foreach (var other in FindVisualChildren<T>(child)) 
        yield return other; 
      } 
      else 
      { 
       yield return (T)child; 
      } 
     } 
    } 

Cuando bucle a través de los TabItems en el XAML registró en la parte inferior, pasando cada una a TabItem el método anterior, pidiéndole que encuentre todos los expansores, no devuelve nada. Además, estoy realizando esta solicitud en un controlador de eventos adjunto al evento cargado de cada elemento de pestaña.



       <TextBlock Text="Number of Parts" Grid.Column="0"/>         
           <ComboBox Grid.Column="2"            
              Margin="0,0,0,2"                                   
              />                
          </Grid> 
         </Expander> 
         <Expander Header="Date/Time Format" 
        Margin="5,0,5,0" 
        Padding="3,3,0,0" 
        IsExpanded="True" > 
          <Grid Margin="20,4,0,4"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="25"/> 
            <RowDefinition Height="Auto"/> 
           </Grid.RowDefinitions> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition/>                 
            <ColumnDefinition Width="*" /> 
           </Grid.ColumnDefinitions> 
           <TextBlock Text="Date/Time Format" Grid.Row="0"/> 
           <ComboBox Name="cmbDateTimeFormats"            
              Grid.Row="0" Grid.Column="2"/> 
          </Grid> 
         </Expander>       
        </StackPanel>      
       </DockPanel> 
      </Border>     
     </TabItem> 
     <TabItem Header="Profile"> 
      <Border > 
       <DockPanel LastChildFill="False"> 
        <StackPanel DockPanel.Dock="Top"> 
         <GroupBox Header="Local" 
           Margin="5,8" Padding="3,3,0,0" 
           >         
          <Grid Margin="20,4,0,4"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="25"/> 
            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="Auto"/> 
           </Grid.RowDefinitions> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition /> 
            <ColumnDefinition /> 
            <ColumnDefinition /> 

            <ColumnDefinition Width="*" /> 
           </Grid.ColumnDefinitions> 

           <Button Content="Location..." Grid.Row="0" Name="btnProfLoc" /> 
           <TextBlock Text="{Binding ProfileLocation}" Grid.Row="0" Grid.Column="2"/> 

           <Button Name="btnSaveProfile" Height="25" 
             Margin="2,5,0,0" Grid.Row="1"           
             Padding="2,1" >          
            <StackPanel Orientation="Horizontal">          
             <TextBlock Text="Save" Margin="5,0"/> 
            </StackPanel> 
           </Button> 

           <Button Name="btnLoadProfile" Height="25" 
             Margin="2,5,0,0" Grid.Row="2"           
             Padding="2,1" > 
            <StackPanel Orientation="Horizontal"> 

             <TextBlock Text="Load" Margin="5,0"/> 
            </StackPanel> 
           </Button> 

           <Button Name="btnResetProfile" Height="25" 
             Margin="2,5,0,0" Grid.Row="3"           
             Padding="2,1" > 
            <StackPanel Orientation="Horizontal">           
             <TextBlock Text="Reset" Margin="5,0"/> 
            </StackPanel> 
           </Button>          
          </Grid> 
         </GroupBox>      
        </StackPanel> 
        <StackPanel 
        DockPanel.Dock="Bottom" Orientation="Horizontal"> 

        </StackPanel> 
       </DockPanel> 
      </Border>     
     </TabItem> 
    </TabControl> 

Cualquier conjetura ¿Qué pasa con mi enfoque? No he intentado con este control personalizado en particular, pero este método se ha usado para buscar elementos secundarios de un tipo determinado en otro control personalizado. La principal diferencia es que los elementos que estoy buscando son hijos de TabItems.

+0

El hecho de que recorras el árbol visual es lo que está mal con este enfoque. ¿Cuál es tu objetivo y qué te hace pensar que esta es la forma en que se debe lograr? –

+0

Your FindVsiaulChildren podría estar equivocado ... pruebe esta implementación ... http: //stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by -type ... también observe el commetn Visual los niños pueden no estar cargados/visibles ... así que use LogicalTreeHelpers. –

+0

@ H.B. Mi Necesito encontrar todos los controles de Expansión en el TabItem después de que se haya cargado. Actualmente, también estoy utilizando este mismo método en otras partes de la aplicación para encontrar objetos de un tipo determinado, en particular, Expansores, y funciona de maravilla. Simplemente no para TabItems. ¿Qué pasa con mi enfoque? –

Respuesta

3

Los controles dentro de una pestaña no parecen ser los elementos secundarios de un TabItem en el árbol visual. Ellos son los hijos de un TabControl.

Puede ver lo que quiero decir si agrega el siguiente código a su aplicación ... e incluye un botón en la pestaña con un controlador de clic que informa sobre la ruta del botón.

public string Id(object control) 
{ 
    if (control is UIElement) 
    { 
     string id = ((UIElement)control).GetValue(AutomationProperties.AutomationIdProperty).ToString(); 
     id += "(" + control.GetType().Name + ")"; 
     return id; 
    } 
    return "not a ui element"; 
} 

private static T FindParent<T>(DependencyObject child) 
    where T : DependencyObject 
{ 
    if (child == null) return null; 
    var parent = VisualTreeHelper.GetParent(child); 
    return parent as T ?? FindParent<T>(parent); 
} 

public string Path(object control) 
{ 
    if (control == null) return ""; 
    var path = Id(control); 
    var parent = FindParent<FrameworkElement>(control as UIElement); 
    if (parent != null) path = Path(parent) +"/"+ path; 
    return path; 
} 

Para mi solicitud me sale el siguiente: "MainForm (MainPage)/(Grid)/(StackPanel)/TabControl (TabControl)/(Grid)/(Grid)/(Border)/(ContentPresenter)/(StackPanel)/Botón (botón) "

Observe TabControl, pero no TabItem.

Si me conecto a eventos del propio TabItem obtengo la siguiente ruta: "MainForm (MainPage)/(Grid)/(StackPanel)/TabControl (TabControl)/(Grid)/(Grid)/(TabPanel)/MyTabItem (TabItem) "

Esto muestra que los elementos no existen dentro del TabItem en el árbol visual, sino como elementos secundarios de TabControl. (Lo cual es una mierda). Nota: se virtualizan y se realizan a medida que cambias las pestañas.