2012-08-24 22 views
5

Tôi có đoạn mã sau C# để tìm con của một DepedendencyObject:VisualTreeHelper.GetChildren không tìm thấy con của 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; 
      } 
     } 
    } 

Khi tôi vòng qua TabItems trong XAML posted ở phía dưới, đi qua mỗi TabItem để các phương pháp trên, yêu cầu nó để tìm tất cả các mở rộng, nó trả về không có gì. Ngoài ra, tôi đang thực hiện yêu cầu này trong trình xử lý sự kiện gắn liền với sự kiện được tải của từng mục tab.



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

Bất kỳ dự đoán những gì là sai với cách tiếp cận của tôi? Tôi đã không cố gắng trong điều khiển tùy chỉnh cụ thể này nhưng phương pháp này đã được sử dụng để tìm trẻ em của một loại nhất định trong một điều khiển tùy chỉnh. Sự khác biệt chính là các mục tôi đang tìm kiếm là con của TabItems.

+0

Thực tế là bạn đi bộ cây thị giác là những gì là sai với phương pháp này. Mục tiêu của bạn là gì và điều gì khiến bạn nghĩ rằng đây là cách nó nên đạt được? –

+0

FindVsiaulChildren của bạn có thể sai ... hãy thử triển khai này ... http: //stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type ... cũng nhận thấy hình ảnh commetn Trực quan trẻ em có thể không được tải/hiển thị .... vì vậy hãy sử dụng LogicalTreeHelpers. –

+0

@ H.B. Tôi cần phải tìm tất cả các điều khiển Mở rộng trong TabItem sau khi đã được tải. Tôi cũng đang sử dụng phương pháp tương tự này trong các phần khác của ứng dụng để tìm các đối tượng của một kiểu nhất định, cụ thể là Expanders, và nó thực hiện thủ thuật. Chỉ cần không cho TabItems. Có gì sai với cách tiếp cận của tôi? –

Trả lời

3

Các điều khiển trong một tab dường như không phải là con của TabItem trong cây thị giác. Họ là con của một TabControl.

Bạn có thể thấy ý của mình nếu bạn thêm mã sau vào ứng dụng của mình .. và bao gồm nút trên tab có trình xử lý nhấp chuột báo cáo Đường dẫn của nút.

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

Đối với ứng dụng của tôi tôi nhận được như sau: "MainForm (Mainpage)/(Grid)/(StackPanel)/TabControl (TabControl)/(Grid)/(Grid)/(Border)/(ContentPresenter)/(StackPanel)/Nút (Nút) "

Chú ý TabControl, nhưng không có TabItem.

Nếu tôi kết nối với các sự kiện từ chính TabItem, tôi nhận được đường dẫn sau: "MainForm (MainPage)/(Grid)/(StackPanel)/TabControl (TabControl)/(Grid)/(Grid)/(TabPanel)/MyTabItem (TabItem) "

Điều này cho thấy các mục không tồn tại trong TabItem trong cây thị giác, nhưng là con của TabControl. (Mà hút.) Lưu ý: chúng được ảo hóa và nhận ra khi bạn thay đổi các tab.