2012-08-24 14 views
5

Mam następujący kod C#, aby znaleźć dzieci w DepedendencyObject:VisualTreeHelper.GetChildren nie znajdzie dzieci 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; 
      } 
     } 
    } 

Kiedy pętla przez TabItems w XAML zamieszczona na dole, przechodząc do każdego TabItem powyższa metoda, z prośbą o znalezienie wszystkich ekspanderów, nie zwraca nic. Składam również to żądanie w procedurze obsługi zdarzenia dołączonej do zdarzenia Loaded dla każdego elementu karty.



       <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> 

Wszelkie domysły co jest nie tak z moim podejściem? Nie próbowałem w tej konkretnej kontroli niestandardowej, ale ta metoda została użyta do znalezienia dzieci danego typu w innej kontrolce niestandardowej. Główną różnicą jest to, że elementy, których szukam, są dziećmi TabItems.

+0

Fakt, że spacerujesz po drzewku wizualnym jest tym, co jest nie tak z tym podejściem. Jaki jest twój cel i co sprawia, że ​​myślisz, że tak właśnie należy to osiągnąć? –

+0

Twój FindVsiaulChildren może się mylić ... wypróbuj tę implementację ... http: //stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by- ... również zauważysz komunikat dzieci nie mogą być załadowane/widoczne .... więc użyj LogicalTreeHelpers. –

+0

@ H.B. Potrzebuję znaleźć wszystkie kontrolki Ekspanderów w TabItem po załadowaniu. Obecnie używam tej samej metody w innych częściach aplikacji, aby znaleźć obiekty danego typu, w szczególności Ekspandery, i to działa. Po prostu nie dla TabItems. Co jest nie tak z moim podejściem? –

Odpowiedz

3

Kontrolki w zakładce nie wydają się być dziećmi elementu TabItem w drzewie wizualnym. Są dziećmi TabControl.

Możesz zobaczyć, co mam na myśli, jeśli dodasz poniższy kod do swojej aplikacji .. i dodasz przycisk na karcie za pomocą obsługi kliknięcia, która zgłasza ścieżkę przycisku.

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; 
} 

dla mojej aplikacji pojawia się następujący: „MainForm (tytułowa)/(siatka)/(StackPanel)/TabControl (TabControl)/(siatka)/(siatka)/(Border)/(ContentPresenter)/(StackPanel)/Button (Button) "

Zwróć uwagę na TabControl, ale nie na TabItem.

Jeśli podłączę się do zdarzeń z samego TabItem, otrzymam następującą ścieżkę: "MainForm (MainPage)/(Grid)/(StackPanel)/TabControl (TabControl)/(Grid)/(Grid)/(TabPanel)/MyTabItem (TabItem) "

To pokazuje, że elementy nie istnieją w TabItem w drzewie wizualnym, ale jako elementy podrzędne TabControl. (Co jest do bani.) Uwaga: są zwirtualizowane i realizowane po zmianie kart.

Powiązane problemy