银光与视觉树操作

发布于 2024-10-07 11:41:50 字数 246 浏览 12 评论 0原文

现在这可能带来的麻烦多于它的价值,但尽管如此,它现在对我来说确实很有用。

我想知道的是如何在运行时操作 Silverlight 可视化树。做一些简单的事情(例如添加和删除控件)很容易,但是当您开始必须以合理的复杂程度遍历树时,我发现自己渴望使用 JQuery 样式语法(我认为 LINQ 也很酷)来处理 DOM 节点替换、动作等。

所以我想问题是是否有任何库可以使这项工作变得更容易,或者是否有一些我错过的东西?

Now this may be more trouble than it's worth but nevertheless, it'd be really useful to me right now.

What I'd like to know is how I might go about manipulating the Silverlight visual tree at runtime. Doing simple things like adding and removing controls is easy enough but when you start having to traverse the tree with any reasonable amount of complexity I find myself yearning for a JQuery style syntax (LINQ would be pretty cool too I suppose) to handle DOM node replacements, movements and the like.

So I guess the question is are there any libraries out there to make this an easier job or is there something baked in that I've missed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

相守太难 2024-10-14 11:41:50

是的,Linq 扩展方法正是您所追求的,但您需要首先放置一个小型基础设施:-

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 来查询可视化树。一些例子:-

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

Yes Linq extension methods are what you are after but you need to put inplace a litte infrastructure first:-

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

Now you can use Linq to query into the visual tree using Linq. Some examples:-

 // 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");
你丑哭了我 2024-10-14 11:41:50

You might be interested in this LINQ to Visual Tree implementation.

场罚期间 2024-10-14 11:41:50

这是什么版本的 silverlight?
这篇文章是哪一年的“12 月 13 日 13:13”?

在当前版本的 SL4 中似乎不存在..

what version of silverlight is this?
And what year of " Dec 13 at 13:13" is this post from?

in the current version of SL4 it does not seem to be there..

影子的影子 2024-10-14 11:41:50

我使用此代码从可视化树中获取控件

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




    }

I use this code to get controls from the visual tree

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




    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文