Silverlight & Visual Tree Manipulation - PullRequest
       8

Silverlight & Visual Tree Manipulation

4 голосов
/ 13 декабря 2010

Теперь это может доставить больше хлопот, чем стоит, но, тем не менее, это было бы очень полезно для меня прямо сейчас.

Что я хотел бы знать, так это то, как я мог бы манипулировать визуальным деревом Silverlight во время выполнения. Делать простые вещи, такие как добавление и удаление элементов управления, достаточно легко, но когда вы начинаете обходить дерево с любой разумной степенью сложности, я испытываю тоску по синтаксису стиля JQuery (LINQ также был бы довольно крутым, я полагаю) для обработки замен DOM , движения и тому подобное.

Так что я думаю, вопрос в том, есть ли какие-нибудь библиотеки, чтобы сделать это более легкой работой, или есть что-то запеченное в том, что я пропустил?

Ответы [ 4 ]

6 голосов
/ 13 декабря 2010

Да. Методы расширения Linq - это то, что вам нужно, но вам нужно сначала разместить инфраструктуру litte: -

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

Теперь вы можете использовать Linq для запроса в визуальном дереве с помощью Linq.Некоторые примеры: -

 // 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");
2 голосов
/ 13 декабря 2010

Вас может заинтересовать эта LINQ to Visual Tree реализация.

0 голосов
/ 20 мая 2014

Я использую этот код для получения элементов управления из визуального дерева

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




    }
0 голосов
/ 21 декабря 2010

какая версия silverlight это? И с какого года "13 декабря в 13:13" это сообщение?

в текущей версии SL4 его там, похоже, нет ..

...