WPF 树视图获取父节点的对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21728283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:49:06  来源:igfitidea点击:

WPF treeview get object of parent node

c#wpftreeview

提问by Matthias

I have a treeview with the following structure:

我有一个具有以下结构的树视图:

Attribute1
  --Value11
  --Value12
Attribute2
  --Value21
  --...
...

The treeview is populated with an HierarchicalDataTemplateof custom classes Attributeand Value.

树视图填充了HierarchicalDataTemplate自定义类AttributeValue.

Now I need to get the parent (attribute) of the currently selected item (value).

现在我需要获取当前选定项(值)的父项(属性)。

What I tried:

我试过的:

DependencyObject obj = treeViewAttributes.ItemContainerGenerator.ContainerFromItem(treeViewAttributes.Items.CurrentItem);
DependencyObject parentNode = ((TreeViewItem)obj).Parent;
Attribute parentAttribute = treeViewAttributes.ItemContainerGenerator.ItemFromContainer(obj) as AttributeType;

However the first line doesn't retrieve the selected object, but the root node. And ContainerFromItem(treeViewAttributes.SelectedItem)returns null.

然而,第一行不检索选定的对象,而是检索根节点。并ContainerFromItem(treeViewAttributes.SelectedItem)返回null

回答by E Vakhovsky

WPF has a reason not to easily return a parent of a tree node. It basically forces you to think of a TreeView in terms of logical vs visual representation. Every node in a tree logically contains an object which on its own level is always created prior to its child, so the best approach to take when you know that you will need access to a parent node is to have a reference to a parent within a child when the child is being created since the parent already always exists. This approach is way more efficient than walking the visual tree in search of a parent

WPF 有理由不轻易返回树节点的父节点。它基本上迫使您根据逻辑与视觉表示来考虑 TreeView。树中的每个节点在逻辑上都包含一个对象,该对象在其自身级别上始​​终先于其子节点创建,因此当您知道需要访问父节点时采取的最佳方法是在一个对象中引用父节点child 当正在创建 child 时,因为 parent 已经始终存在。这种方法比在视觉树中寻找父节点更有效

回答by Johannes91

I tried running through treeView and use GetHashCode for finding parent treeViewItem and it worked well for me. I don't know how the performance is, but I think that should not be a problem:

我尝试通过 treeView 运行并使用 GetHashCode 来查找父 treeViewItem,它对我来说效果很好。我不知道性能如何,但我认为这应该不是问题:

private TreeViewItem GetParent(TreeViewItem root, TreeViewItem child)
    {
        //Step 1: Search at current level
        foreach (TreeViewItem item in root.Items)
        {
            if (item.GetHashCode() == child.GetHashCode())
            {
                return root;
            }
        }

        //Step 2: Still not found, so step deeper
        TreeViewItem buffer;
        foreach (TreeViewItem item in root.Items)
        {
            buffer = GetParent(item, child);
            if (buffer != null)
            {
                return buffer;
            }
        }

        //Not found anything
        return null;
    }

回答by Adam

Use the helper class in this blog

使用本博客中的助手类

https://rachel53461.wordpress.com/2011/10/09/navigating-wpfs-visual-tree/

https://rachel53461.wordpress.com/2011/10/09/navigating-wpfs-visual-tree/

    /// <summary>
    /// Returns the first ancester of specified type
    /// </summary>
    public static T FindAncestor<T>(DependencyObject current)
    where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);

        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        };
        return null;
    }

Then you can get the parent with this call

然后你可以通过这个电话获得父母

var parent = VisualTreeHelpers.FindAncestor<Attribute>(Value);

回答by Microsoft DN

Try following code

试试下面的代码

private void yourTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    if (sender is TreeView && ((TreeViewItem)((TreeView)sender).SelectedItem).Parent != null)
    {
        TreeViewItem parent = (TreeViewItem)((TreeViewItem)((TreeView)sender).SelectedItem).Parent;  // This will give you the parent             
    }
}