2010-12-13 6 views
4

Jetzt kann mehr Ärger als es wert sein, aber nichtsdestoweniger, es wäre wirklich nützlich für mich jetzt.Silverlight & Visual Tree Manipulation

Was ich gerne wissen würde, ist, wie ich den Silverlight Visual Tree zur Laufzeit manipulieren könnte. Einfache Dinge wie das Hinzufügen und Entfernen von Steuerelementen sind einfach, aber wenn Sie anfangen, den Baum mit einer angemessenen Komplexität zu durchlaufen, sehne ich mich nach einer JQuery-Stil-Syntax (LINQ wäre auch ziemlich cool), um DOM-Knoten zu ersetzen , Bewegungen und dergleichen.

Also die Frage ist, gibt es irgendwelche Bibliotheken da draußen, um dies zu einem leichteren Job zu machen, oder ist da etwas gebacken, das ich verpasst habe?

Antwort

6

Ja Linq-Erweiterungsmethoden sind, was Sie nach, aber Sie müssen zuerst inplace eine litte Infrastruktur setzen: -

public static class VisualTreeEnumeration 
{ 
    public static IEnumerable<DependencyObject> Descendents(this DependencyObject root, int depth) 
    { 
     int count = VisualTreeHelper.GetChildrenCount(root); 
     for (int i = 0; i < count; i++) 
     { 
      var child = VisualTreeHelper.GetChild(root, i); 
      yield return child; 
      if (depth > 0) 
      { 
       foreach (var descendent in Descendents(child, --depth)) 
        yield return descendent; 
      } 
     } 
    } 

    public static IEnumerable<DependencyObject> Descendents(this DependencyObject root) 
    { 
      return Descendents(root, Int32.MaxValue); 
    } 

    public static IEnumerable<DependencyObject> Ancestors(this DependencyObject root) 
    { 
      DependencyObject current = VisualTreeHelper.GetParent(root); 
      while (current != null) 
      { 
       yield return current; 
       current = VisualTreeHelper.GetParent(current); 
      } 
    } 
} 

Jetzt können Sie Linq in der visuellen Struktur abzufragen verwenden mithilfe von Linq. Einige Beispiele: -

// Get all text boxes in usercontrol:- 
this.Descendents().OfType<TextBox>(); 

// All UIElement direct children of the layout root grid:- 
LayoutRoot.Descendents(0).OfType<UIElement>(); 

// Find the containing `ListBoxItem` for an element:- 
elem.Ancestors().OfType<ListBoxItem>.FirstOrDefault(); 

// Seek button with name "PinkElephants" even if outside of the current Namescope:- 
this.Descendents() 
    .OfType<Button>() 
    .FirstOrDefault(b => b.Name == "PinkElephants"); 
+0

awesome ... Dank ein Bündel zu erhalten. – Stimul8d

0

Welche Version von Silverlight ist das? Und welches Jahr von "13. Dezember um 13:13" ist dieser Beitrag von?

in der aktuellen Version von SL4 es nicht da ..

0

ich diesen Code verwenden, um zu sein scheint Steuerelemente aus der visuellen Struktur

public static FrameworkElement GetComponent(object child, Type t, Type bailOn) 
    { 
     if (child == null) return null; 

     DependencyObject control = (DependencyObject)child; // VisualTreeHelper.GetParent((DependencyObject)x); 

     while (control != null) 
     { 
      if (!control.Equals(child)) 
      { 
       if (control.GetType() == t) 
       { 
        break; 
       } 
      } 

      if (control is FrameworkElement) 
      { 
       control = (control as FrameworkElement).Parent; 
      } 
      else if ((control is DataGridBoundColumn)) // data grid fucken columns 
      { 
       control = GetDataGridBoundColumnDataGrid(control); 

      } 
      if (control != null && bailOn != null && bailOn.GetType() == control.GetType()) 
      { 
       return null; 
      } 

     } 

     // try VTH as we did not find it, as that works some times and the above does not 
     if (control == null) 
     { 
      control = (DependencyObject)child; // start again 

      while (control != null) 
      { 
       if (!control.Equals(child)) 
       { 
        if (control.GetType() == t) 
        { 
         break; 
        } 
       } 
       if (control is FrameworkElement) 
       { 
        control = VisualTreeHelper.GetParent((control as FrameworkElement)); 
       } 
       else if (control is DataGridBoundColumn) 
       { 
        control = GetDataGridBoundColumnDataGrid(control); 
       } 

       if (control != null && bailOn != null && bailOn.GetType() == control.GetType()) 
       { 
        return null; 
       } 

      } 

     } 
     return control as FrameworkElement; 
    } 

    public static List<FrameworkElement> GetComponentsByType(FrameworkElement parent, Type type) 
    { 
     List<FrameworkElement> controls = new List<FrameworkElement>(); 
     GetComponentsByTypeWorker(parent, type, controls); 
     return controls; 

    } 
    private static void GetComponentsByTypeWorker(FrameworkElement parent, Type type, List<FrameworkElement> controls) 
    { 

     if (parent.GetType() == type) 
     { 
      controls.Add(parent as FrameworkElement); 
     } 

     int cnt = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < cnt; i++) 
     { 
      FrameworkElement child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement; 
      if (child.GetType() == type) 
      { 
       controls.Add(child as FrameworkElement); 
      } 

      int cnt2 = VisualTreeHelper.GetChildrenCount(child); 
      for (int j = 0; j < cnt2; j++) 
      { 
       FrameworkElement child2 = VisualTreeHelper.GetChild(child, j) as FrameworkElement; 

       GetComponentsByTypeWorker(child2 as FrameworkElement, type, controls); 
      } 
     } 




    }