2009-05-17 6 views
16

Wie durchlaufe ich alle Steuerelemente in einem Fenster in WPF?WPF: Wie durchlaufe ich alle Steuerelemente in einem Fenster?

+2

könnte Dieser Link einen guten Anfang sein: http://msdn.microsoft.com/en-us/library/bb613556.aspx – VVS

+0

Sie die Antwort in finden: http://stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type –

Antwort

7

Klasse eine Liste aller Kinder Komponenten einer Kontrolle zu bekommen:

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); 
       } 
      } 
     } 
    } 
+2

Das Durchschleifen eines logischen Baums ist nicht besser und effizienter als das Durchlaufen eines visuellen Baums. – MegaMind

+0

'sbListControls' sollte eine lokale Variable sein, falls diese Methoden gleichzeitig von mehreren Threads aufgerufen werden. –

14

Ich fand dies in der MSDN documenation so hilft es.

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

Sieht einfacher für mich. Ich habe es verwendet, um Textfelder in einem Formular zu finden und ihre Daten zu löschen.

+0

posted ich eine andere Antwort auf dieser Basis, die tatsächlich gibt ein 'IEnumerable ', so dass der Endbenutzer kann nur eine regelmäßige for-Schleife verwenden, etc. Das macht die Kinder-Kollektion sehr einfach aufzählt, und ermöglicht eine frühe Abtreibung über 'brechen; 'usw. Schau es dir an. – BrainSlugs83

+0

Wenn ich versuche, das ich einen Fehler zu reproduzieren, erhalten auf myVisual (dh .GetChildrenCount (** myVisual **) & .GetChild (** myVisual ** i)) sagen „kann nicht von‚Windows.UI.Composition.Visual konvertieren 'zu' Windows.UI.Xaml.DependencyObject '"? Funktionieren WPF-Lösungen in der UWP-Umgebung? Verwende ich die falsche using-Direktive (Windows.UI.Composition)? – gaw

0

Eine leichte Variation auf der MSDN-Antwort ... geben Sie einfach in eine leere Liste von Visual Objekte hinein und Ihre Sammlung wird mit allen Kind Visuals werden bevölkert:

/// <summary> 
/// Enumerate all the descendants (children) of a visual object. 
/// </summary> 
/// <param name="parent">Starting visual (parent).</param> 
/// <param name="collection">Collection, into which is placed all of the descendant visuals.</param> 
public static void EnumVisual(Visual parent, List<Visual> 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); 
    } 
} 
+0

posted ich eine andere Antwort, basierend auf Ihr, die tatsächlich einen 'IEnumerable gibt ' so dass der Benutzer Ende nur eine regelmäßige for-Schleife verwenden können usw. Das spart den Aufwand, eine Liste zu erstellen, und ermöglicht eine frühe Abtreibung über 'brechen; 'usw. Schau es dir an. – BrainSlugs83

8

Auf diese Weise überlegen ist die MSDN-Methode, in der es wiederverwendbar ist, und es ermöglicht einen frühen Abbruch der Schleife (zB via, break;, etc.) - es optimiert die for-Schleife in dem es einen Methodenaufruf für jede Iteration speichert - und Sie können es auch verwenden Regelmäßige for-Schleifen, um die Kinder eines Visual zu durchlaufen, oder sogar die Kinder und die Enkelkinder zu rekursieren - es ist also viel einfacher zu konsumieren.

es zu verbrauchen, können Sie einfach eine regelmäßige foreach-Schleife schreiben (oder sogar LINQ):

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

Oder, wenn Sie nicht Rekursion wollen:

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

zu machen Arbeit, Sie müssen nur diese Erweiterung Methode in jede statische Klasse setzen, und dann werden Sie in der Lage sein, Code wie die oben jederzeit schreiben Sie mögen:

public static IEnumerable<Visual> 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; 
        } 
       } 
      } 
     } 
    } 
} 

Wenn Sie nicht möchten, dass die Rekursion standardmäßig aktiviert ist, können Sie die Deklaration der Erweiterungsmethode so ändern, dass recurse = false das Standardverhalten ist.

1

Ich habe folgendes zu bekommen alle Kontrollen verwendet.

public static IList<Control> GetControls(this DependencyObject parent) 
    {    
     var result = new List<Control>(); 
     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; 
    } 
Verwandte Themen