【问题标题】:Get parent TreeViewItem of a selected node in WPF获取 WPF 中选定节点的父 TreeViewItem
【发布时间】:2014-10-29 07:39:20
【问题描述】:

我想要一个被选为 TreeViewItem 的节点的父节点

我有一个包含 2 个字段的 Person 类。名称(字符串)和子项(字符串列表)

这是我的 xaml 代码

<Grid x:Name="gridView" Margin="10">
    <TreeView Name="treeView1" TreeViewItem.Selected="TreeViewItem_OnItemSelected" ItemsSource="{Binding}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsSelected" Value="{Binding IsSelected, Source=Check, Mode=TwoWay}" />
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type loc:Person}" ItemsSource="{Binding Children}" >
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>
</Grid>

这是我的代码。 我将项目源设置为 Person 对象列表。

void set()
{
    if (treeView1.Items.IndexOf(treeView1.SelectedItem) != -1)
    {
        //is a parent 
        //returns -1 for children
        Person selected = (Person)treeView1.SelectedItem;
        int index = search(selected);
        TreeViewItem parent = treeView1.Tag as TreeViewItem;
        setSelected(parent,index);
    }
    else
    {
        //is a child
        TreeViewItem child = treeView1.Tag as TreeViewItem; //returns the selected node
        TreeViewItem parent = child.Parent as TreeViewItem; //returns null
    }
}
private void TreeViewItem_OnItemSelected(object sender, RoutedEventArgs e)
{
    treeView1.Tag = e.OriginalSource;
    int ind = 0;
    foreach (var _item in treeView1.Items)
    {
        if (_item == treeView1.SelectedItem)
        {
            selectedIndex = ind;
            break;
        }
        ind++;
    }
}

在 else 部分,child.Parent 总是返回 null。我尝试了其他方法,但没有一个返回TreeViewItem,而是返回DependencyObjectItemsControl

我也尝试了ContainerFromItem 方法,但它只适用于直接子(父)而不是父的子。

请帮忙

【问题讨论】:

  • 在 WPF UI 中导航有时非常棘手。如果您找不到实现此目的的方法,只需尝试在您的 Person 类中添加一个 Parent ,这会使导航变得更加容易。

标签: c# wpf treeview wpf-controls treeviewitem


【解决方案1】:

您可以使用VisualTreeHelper.GetParent() 方法: https://msdn.microsoft.com/de-de/library/system.windows.media.visualtreehelper.getparent(v=vs.110).aspx

示例代码:

private TreeViewItem FindParentTreeViewItem(object child)
{
    try
    {
        var parent = VisualTreeHelper.GetParent(child as DependencyObject);
        while ((parent as TreeViewItem) == null)
        {
            parent = VisualTreeHelper.GetParent(parent);
        }
        return parent as TreeViewItem;
    }
    catch (Exception e)
    {
        //could not find a parent of type TreeViewItem
        return null;
    }
}

需要 while 循环,因为树视图项的可视父项不是其父树视图项,如在此 WPF 树可视化工具中所示:

WPF Tree Visualizer showing tree view

【讨论】:

    【解决方案2】:

    ItemsSource 通常是您可以绑定到的 DependencyObjects 的集合。它不反映有关 UI 的任何信息。您正在寻找的实际上是每个 Item 的 ItemContainer,它是 WPF UI 的一部分。

    在大多数情况下,您可以毫无问题地从另一个 UIElement 访问。但根据我的经验,随着样式、模板和分层项使 UI 变得复杂,一些 UIElement 将很难找到。

    我建议如下方式:

    在你的ViewModel(Person Class)中实现一个Person类型的Parent属性,并在Person的构造函数中初始化它,然后你可以像这样获取父Person和父TreeViewItem:

    var parentPerson = (treeView1.SelectedItem as Person).Parent;
    var parentNode = treeView1.ItemContainerGenerator.ContainerFromItem(parentPerson);
    

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      相关资源
      最近更新 更多