WPF: Come faccio a scorrere tutti i controlli in una finestra?

Come faccio a scorrere tutti i controlli in una finestra in WPF?

Classe per ottenere un elenco di tutti i componenti dei bambini di un controllo:

class Utility { private static StringBuilder sbListControls; public static StringBuilder GetVisualTreeInfo(Visual element) { if (element == null) { throw new ArgumentNullException(String.Format("Element {0} is null !", element.ToString())); } sbListControls = new StringBuilder(); GetControlsList(element, 0); return sbListControls; } private static void GetControlsList(Visual control, int level) { const int indent = 4; int ChildNumber = VisualTreeHelper.GetChildrenCount(control); for (int i = 0; i < = ChildNumber - 1; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(control, i); sbListControls.Append(new string(' ', level * indent)); sbListControls.Append(v.GetType()); sbListControls.Append(Environment.NewLine); if (VisualTreeHelper.GetChildrenCount(v) > 0) { GetControlsList(v, level + 1); } } } } 

Ho trovato questo nella documenation MSDN quindi aiuta.

 // Enumerate all the descendants of the visual object. static public void EnumVisual(Visual myVisual) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++) { // Retrieve child visual at specified index value. Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i); // Do processing of the child visual object. // Enumerate children of the child visual object. EnumVisual(childVisual); } } 

Sembra più semplice per me. L'ho usato per trovare caselle di testo in un modulo e cancellare i loro dati.

In questo modo è superiore al metodo MSDN, nel senso che è riutilizzabile e consente l’ break; anticipata del ciclo (es. Via, break; , ecc.) – ottimizza il ciclo for in quanto salva una chiamata al metodo per ogni iterazione – – Inoltre, consente di utilizzare loop regolari per looping attraverso i figli di un Visual, o anche di recitare i suoi figli ed è grandioso – quindi è molto più semplice da consumare.

Per consumarlo, puoi semplicemente scrivere un ciclo foreach regolare (o anche usare LINQ):

 foreach (var ctrl in myWindow.GetChildren()) { // Process children here! } 

O se non vuoi recitare:

 foreach (var ctrl in myWindow.GetChildren(false)) { // Process children here! } 

Per farlo funzionare, devi solo inserire questo metodo di estensione in qualsiasi class statica, e quindi sarai in grado di scrivere il codice come sopra ogni volta che vuoi:

 public static IEnumerable GetChildren(this Visual parent, bool recurse = true) { if (parent != null) { int count = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < count; i++) { // Retrieve child visual at specified index value. var child = VisualTreeHelper.GetChild(parent, i) as Visual; if (child != null) { yield return child; if (recurse) { foreach (var grandChild in child.GetChildren(true)) { yield return grandChild; } } } } } } 

Inoltre, se non ti piace la ricorsione triggers per impostazione predefinita, puoi modificare la dichiarazione del metodo di estensione in modo che recurse = false sia il comportamento predefinito.

Ho usato quanto segue per ottenere tutti i controlli.

  public static IList GetControls(this DependencyObject parent) { var result = new List(); for (int x = 0; x < VisualTreeHelper.GetChildrenCount(parent); x++) { DependencyObject child = VisualTreeHelper.GetChild(parent, x); var instance = child as Control; if (null != instance) result.Add(instance); result.AddRange(child.GetControls()); } return result; } 

Una leggera variazione sulla risposta MSDN … basta passare in un elenco vuoto di oggetti visivi e la tua raccolta verrà popolata con tutte le immagini secondarie:

 ///  /// Enumerate all the descendants (children) of a visual object. ///  /// Starting visual (parent). /// Collection, into which is placed all of the descendant visuals. public static void EnumVisual(Visual parent, List collection) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { // Get the child visual at specified index value. Visual childVisual = (Visual)VisualTreeHelper.GetChild(parent, i); // Add the child visual object to the collection. collection.Add(childVisual); // Recursively enumerate children of the child visual object. EnumVisual(childVisual, collection); } }