2012-04-23 1 views
29

Как я могу получить дочерние элементы управления типа ComboBox в MyContainerGrid в WPF?Как получить детей из контейнера WPF по типу?

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

Эта линия дает мне ошибку:

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

ответ

63

Этот метод расширение будет искать рекурсивен для дочерних элементов желаемый тип:

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

Таким образом, используя это, вы можете запросить MyContainer.GetChildOfType<ComboBox>().

+7

' LogicalTreeHelper.FindLogicalNode (DependencyObject depObj, string elementName) 'работал для меня, чтобы достичь той же цели. – Paul

+0

Используйте этот http://stackoverflow.com/a/978352/690656 – Andreas

32

Дети это коллекция UiElements. Поэтому вам нужно перебирать элементы и определять для каждого элемента, является ли он требуемого типа. К счастью, уже есть метод Linq для именно это, а именно Enumerable.OfType<T>, который вы можете удобно звонить с помощью Extension Method синтаксис:

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

Этот метод фильтрует сбор в зависимости от их типа и возвращается, в вашем случае, только элементы типа ComboBox.

Если вы хотите только первый ComboBox (как переменное имя может предложить), вы можете просто добавить вызов FirstOrDefault() к запросу:

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

хорошо работает. Спасибо – ArchieTiger

+1

Это не будет искать в 'ContentControl –

2

Поиска первого ребенка определенного типа, который включает в себя заданную точку (на экране):

(пары «точка» является результатом вызова функции «PointToScreen» (объявленной в визуальном типе))

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

Пожалуйста, отредактируйте более подробную информацию. Только код и «попробуйте» ответы [обескуражены] (// meta.stackexchange.com/questions/196187), потому что они не содержат содержимого, доступного для поиска, и не объясняют, почему кто-то должен «попробовать это». Мы прилагаем усилия, чтобы стать источником знаний. – Mogsdad

Смежные вопросы