【问题标题】:VisualTreeHelper not finding children of DependencyObject, How can I reliably find objects?VisualTreeHelper 没有找到 DependencyObject 的子项,我怎样才能可靠地找到对象?
【发布时间】:2012-11-06 09:24:57
【问题描述】:

我有一个名为ZoneContainer 的用户控件。这有一个包含ListBox 的属性,其中包含许多ListItems。每个 ListItem 都包含一个DockPanel

我正在尝试使用以下代码来查找存在于 ZoneContainer 中的孩子,但 childrenCount 每次都是 0。

var parent = this as DependencyObject; // I can see that this is populated.

int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

还有其他方法可以在对象列表中找到特定的子对象吗?最终我试图找到 DockPanel,但它没有找到任何孩子,即使我知道他们在对象中。

【问题讨论】:

  • 你是在ZoneContainer的构造函数中调用这个吗?
  • @Clemens,是的,我是......我想我可以看到你的问题在哪里。对象尚未创建?
  • 是的,尝试在 Loaded 事件处理程序中执行此操作。

标签: c# wpf user-controls visualtreehelper dependencyobject


【解决方案1】:

这里的基本问题是不是所有的孩子都是 VisualTree 的一部分
您可以在 Josh Smith 的 articel 中找到有关此问题的更多信息

这是我获取所有孩子的扩展

    public static IEnumerable<DependencyObject> getChilds(this DependencyObject parent)
    {
        if (parent == null) yield break;

        //use the logical tree for content / framework elements
        foreach (object obj in LogicalTreeHelper.GetChildren(parent))
        {
            var depObj = obj as DependencyObject;
            if (depObj != null)
                yield return depObj;
        }

        //use the visual tree for Visual / Visual3D elements
        if (parent is Visual || parent is Visual3D)
        {
            int count = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < count; i++)
            {
                yield return VisualTreeHelper.GetChild(parent, i);
            }
        }
    }

【讨论】:

    【解决方案2】:

    这是我藏在图书馆里的函数。我从来没有遇到过任何问题,但它确实有一个 GetChildrenCount() 调用,所以如果这对你不起作用,你可能会遇到更大的问题。

    Public Shared Function FindVisualChild(Of T As DependencyObject)(ByVal element As DependencyObject) As T
        If element Is Nothing Then
            Return Nothing
        ElseIf TypeOf (element) Is T Then
            Return element
        Else
            Dim count = VisualTreeHelper.GetChildrenCount(element)
            For index As Integer = 0 To count - 1
                Dim child As DependencyObject = VisualTreeHelper.GetChild(element, index)
                If TypeOf (child) Is T Then
                    Return child
                Else
                    Dim grandchild As T = FindVisualChild(Of T)(child)
                    If grandchild IsNot Nothing Then Return grandchild
                End If
            Next
        End If
    
        Return Nothing
    End Function
    

    用法:x = FindVisualChild(Of DockPanel)(ParentObject)

    是的,我知道它是 VB。现在是你们中的一个 C# 人员必须转换代码一次的时候了! :)

    【讨论】:

      【解决方案3】:

      我通过查询对象而不是爬取可视化树解决了这个问题。

      var header = container.ListBox.Items.Cast<ListBoxItem>()
          .Select(item => (MyType) item.Content)
          .FirstOrDefault(myType => myType.dpHeader.Name == "whatever").dpHeader;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多