2012-04-23 9 views
29

Come posso ottenere i controlli figlio di tipo ComboBox in MyContainerGrid in WPF?Come ottenere figli da un contenitore WPF per tipo?

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

Questa linea mi dà un errore:

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

risposta

63

Questo metodo di estensione cercherà in modo ricorsivo per gli elementi figlio del tipo desiderato:

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

Quindi usando quello si può chiedere per MyContainer.GetChildOfType<ComboBox>().

+7

' LogicalTreeHelper.FindLogicalNode (DependencyObject depObj, string elementName) 'ha funzionato per me per raggiungere lo stesso obiettivo. – Paul

+0

Utilizzare questo http://stackoverflow.com/a/978352/690656 – Andreas

32

Bambini è una raccolta di UIElements. Quindi è necessario scorrere gli articoli e determinare per ogni voce se è del tipo richiesto. Per fortuna, c'è già un metodo Linq proprio per questo, vale a dire Enumerable.OfType<T>, che si può comodamente chiamare utilizzando Extension Method sintassi:

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

Questo metodo filtra la collezione in base al tipo e ritorna, nel tuo caso, solo gli elementi di tipo ComboBox.

Se si desidera solo la prima casella combinata (come il tuo nome della variabile potrebbe suggerire), si può solo aggiungere una chiamata al FirstOrDefault() alla query:

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

funziona bene. Grazie – ArchieTiger

+1

Questo non cercherà in 'ContentControl –

2

Ricerca per il primo figlio di un certo tipo che comprende un punto (su schermo) predeterminato:

(param 'punto' è il risultato della chiamata funzione 'PointToScreen' (dichiarata nel tipo visivo))

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

Si prega di [modificare] con ulteriori informazioni. Le risposte solo per codice e "prova questo" sono [scoraggiate] (// meta.stackexchange.com/questions/196187), perché non contengono contenuti ricercabili e non spiegano perché qualcuno dovrebbe "provare questo". Facciamo uno sforzo qui per essere una risorsa per la conoscenza. – Mogsdad