2012-04-23 12 views
29

Jak mogę uzyskać formanty podrzędne typu ComboBox w MyContainerGrid w WPF?Jak zdobyć dzieci kontenera WPF według typu?

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

Linia ta daje mi błąd:

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

Odpowiedz

63

Ta metoda rozszerzenie będzie wyszukiwać rekursywnie elementów podrzędnych żądany typ:

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

Używając tego, możesz poprosić o MyContainer.GetChildOfType<ComboBox>().

+7

' LogicalTreeHelper.FindLogicalNode (DependencyObject depObj, string elementName) 'pracował dla mnie, aby osiągnąć ten sam cel. – Paul

+0

Użyj tego http://stackoverflow.com/a/978352/690656 – Andreas

32

Dzieci jest zbiorem UIElements. Musisz więc powtórzyć elementy i określić dla każdego przedmiotu, czy jest on wymaganego typu. Na szczęście jest już metoda LINQ do dokładnie tego, mianowicie Enumerable.OfType<T>, który można wygodnie wywołać za pomocą Extension Method składnię:

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

Metoda ta filtruje zbiór zależności od ich rodzaju i zwrotów, w przypadku, tylko elementy typu ComboBox.

Jeśli chcesz tylko pierwszy ComboBox (jako zmienna nazwa może sugerować), można po prostu dołączyć wezwanie do FirstOrDefault() do zapytania:

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

działa dobrze. Dzięki – ArchieTiger

+1

Nie będzie szukać w 'ContentControl –

2

Szukaj pierwszego dziecka pewnego rodzaju, który zawiera ustaloną temperaturę (ekranu):

(param „punkt” jest wynikiem wywołania funkcji „PointToScreen” (zadeklarowanego typu wizualna))

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

Proszę [edytuj] z dodatkowymi informacjami. Tylko kod i odpowiedzi "spróbuj tego" są zniechęcane (// meta.stackexchange.com/questions/196187), ponieważ nie zawierają treści do wyszukiwania i nie wyjaśniają, dlaczego ktoś powinien "spróbować tego". Staramy się być źródłem wiedzy. – Mogsdad

Powiązane problemy