2010-12-13 29 views
4

Maintenant, ce peut être plus de mal que ça vaut la peine, mais néanmoins, ce serait vraiment utile pour moi maintenant.Silverlight & Visual Tree Manipulation

Ce que j'aimerais savoir, c'est comment je pourrais manipuler l'arborescence visuelle Silverlight à l'exécution. Faire des choses simples comme l'ajout et la suppression de contrôles est assez facile mais quand vous commencez à devoir traverser l'arborescence avec une complexité raisonnable, je suis impatient d'avoir une syntaxe de style JQuery (LINQ serait plutôt cool) , les mouvements et autres.

Donc, je suppose que la question est de savoir s'il existe des bibliothèques pour faciliter la tâche ou y a-t-il quelque chose que j'ai raté?

Répondre

6

Oui Linq méthodes d'extension sont ce que vous recherchez, mais vous avez besoin de mettre enplace une infrastructure litte première: -

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

Maintenant, vous pouvez utiliser LINQ pour interroger dans l'arbre visuel en utilisant Linq. Quelques exemples: -

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

impressionnant ... Remercie un groupe. – Stimul8d

0

quelle version de silverlight est-ce? Et quelle est l'année de "Dec 13 à 13:13"?

dans la version actuelle de SL4 il ne semble pas être là ..

0

J'utiliser ce code pour obtenir des commandes de l'arbre visuel

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




    }