2012-04-23 26 views
29

Tôi làm cách nào để có được các điều khiển con của loại ComboBox trong MyContainerGrid trong WPF?Làm thế nào để có được con của một thùng chứa WPF theo loại?

<Grid x:Name="MyContainer">      
    <Label Content="Name" Name="label1" /> 
    <Label Content="State" Name="label2" /> 
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox1"/> 
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox3" /> 
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox4" /> 
</Grid> 

Dòng này mang lại cho tôi một lỗi:

var myCombobox = this.MyContainer.Children.GetType(ComboBox); 

Trả lời

63

phương pháp Phần mở rộng này sẽ tìm kiếm một cách đệ quy cho các yếu tố con của loại mong muốn:

public static T GetChildOfType<T>(this DependencyObject depObj) 
    where T : DependencyObject 
{ 
    if (depObj == null) return null; 

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
    { 
     var child = VisualTreeHelper.GetChild(depObj, i); 

     var result = (child as T) ?? GetChildOfType<T>(child); 
     if (result != null) return result; 
    } 
    return null; 
} 

Do đó bạn có thể yêu cầu MyContainer.GetChildOfType<ComboBox>().

+7

' LogicalTreeHelper.FindLogicalNode (DependencyObject depObj, string elementName) 'đã làm việc cho tôi để đạt được cùng một mục tiêu. – Paul

+0

Sử dụng http://stackoverflow.com/a/978352/690656 – Andreas

32

Trẻ em là một tập hợp các UIElements. Vì vậy, bạn cần phải lặp qua các mục và xác định cho mỗi mục cho dù đó là loại yêu cầu. May mắn thay, đã có một phương pháp LINQ cho chính xác này, cụ thể là Enumerable.OfType<T>, mà bạn có thể thoải mái gọi sử dụng Extension Method cú pháp:

var comboBoxes = this.MyContainer.Children.OfType<ComboBox>(); 

Phương pháp này lọc bộ sưu tập dựa trên loại và lợi nhuận của họ, trong trường hợp của bạn, chỉ có các yếu tố của loại ComboBox.

Nếu bạn chỉ muốn ComboBox đầu tiên (như tên biến của bạn có thể đề nghị), bạn chỉ có thể thêm một cuộc gọi đến FirstOrDefault() với truy vấn:

var myComboBox = this.MyContainer.Children.OfType<ComboBox>().FirstOrDefault(); 
+0

hoạt động tốt. Cảm ơn – ArchieTiger

+1

Điều này sẽ không tìm kiếm trong 'ContentControl –

2

Tìm kiếm đứa trẻ đầu tiên của một loại nhất định mà bao gồm một điểm định trước (của màn hình):

(param 'điểm' là kết quả của gọi hàm 'PointToScreen' (công bố trong Visual type))

private TDescendantType FindDescendant<TDescendantType>(DependencyObject parent, Point screenPoint) 
     where TDescendantType : DependencyObject 
{ 
    int count = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < count; i++) 
    { 
     var child = VisualTreeHelper.GetChild(parent, i); 
     if (child is Visual) 
     { 
      Point point = ((Visual)child).PointFromScreen(screenPoint); 
      Rect rect = VisualTreeHelper.GetDescendantBounds((Visual)child); 

      if (!rect.Contains(point)) 
       continue; 
     } 

     if (child is TDescendantType) 
     { 
      return (TDescendantType)child; 
     } 

     child = FindDescendant<TDescendantType>(child, screenPoint); 
     if (child != null) 
     { 
      return (TDescendantType)child; 
     } 
    } 
    return null; 
} 
+0

Vui lòng chỉnh sửa với nhiều thông tin hơn. Chỉ có mã và câu trả lời "dùng thử" này mới được [nản lòng] (// meta.stackexchange.com/questions/196187), vì chúng không chứa nội dung có thể tìm kiếm được và không giải thích tại sao một người nào đó nên "thử cái này". Chúng tôi nỗ lực ở đây để trở thành một nguồn lực cho kiến ​​thức. – Mogsdad

Các vấn đề liên quan