在TreeView中获取选定项的TreeViewItem

17
我有一个TreeView,它绑定了一个具有父子关系的数据集。如何从TreeView中获取所选的TreeViewItem?请帮帮我。我的代码如下。
xaml: -
<TreeView Name="tvPersonal"  Background="Transparent"  ItemsSource="{Binding RootNodes}" SelectedItemChanged="tvPersonal_SelectedItemChanged">    
 <TreeView.ItemTemplate>
   <HierarchicalDataTemplate ItemsSource="{Binding rsParentChild}">
     <TextBlock Text="{Binding Name}" />
   </HierarchicalDataTemplate>
 </TreeView.ItemTemplate>

 public MainWindow()   

        {    
            InitializeComponent();    
            DataSet ds = new BL.BLMenu().GetAllMenues(new BOModule { Name = Modules.Personnel });
            ds.Tables[0].TableName = "Menu";
            DataRelation relation = new DataRelation("rsParentChild",
                    ds.Tables["Menu"].Columns["MenuId"],
                    ds.Tables["Menu"].Columns["ParentId"]);
            relation.Nested = true;    
            ds.Relations.Add(relation);
            BOMenu mnu = new BOMenu();    
            BOMenu.RootNodes = ds.Tables["Menu"].DefaultView;
            BOMenu.RootNodes.RowFilter = "ParentId IS NULL";    

            this.DataContext = this;
            stbiDate.Content = DateTime.Now;

        }
        public DataView RootNodes    
        {
            get { return BOMenu.RootNodes; }
        }

BOMenu类:

 public class BOMenu
    {
        public string MenuId
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public string ParentId
        {
            get;
            set;
        }

        public int Priority
        {
            get;
            set;
        }

        public static DataView RootNodes
        {
            get;
            set;
        }

    }
4个回答

19

虽然 biju 的答案适用于平坦的层次结构,但我需要寻找 HierarchicalDataTemplates 的解决方案。这是对我有用的扩展方法:

public static TreeViewItem ContainerFromItemRecursive(this ItemContainerGenerator root, object item)
{
    var treeViewItem = root.ContainerFromItem(item) as TreeViewItem;
    if (treeViewItem != null)
        return treeViewItem;
    foreach (var subItem in root.Items)
    {
        treeViewItem = root.ContainerFromItem(subItem) as TreeViewItem;
        var search = treeViewItem?.ItemContainerGenerator.ContainerFromItemRecursive(item);
        if (search != null)
            return search;
    }
    return null;
}
您可以与它一起使用。
TreeViewItem tvi = treeView
                       .ItemContainerGenerator
                       .ContainerFromItemRecursive(treeView.SelectedItem);

6
看起来这样做就可以解决问题了!2012年我需要这个的时候你在哪里呢 :) - Roman Starkov

13

21
对于数据源是通过“HierarchicalDataTemplate”绑定的树形结构,此方法不适用。 - Roman Starkov
无法通过这种方式获取孙子。 - Jo Smo

8

这适用于数据源通过HierarchicalDataTemplate绑定的树形结构

处理TreeViewItem.Selected事件

<TreeView Name="mTreeView" TreeViewItem.Selected="TreeViewItem_OnItemSelected" />

将TreeViewItem设置为标记。

private void TreeViewItem_OnItemSelected(object sender, RoutedEventArgs e)
{
    mTreeView.Tag = e.OriginalSource;
}

您可以随后检索的内容

TreeViewItem tvi = mTreeView.Tag as TreeViewItem;

你如何在代码中编写 TreeViewItem.Selected="TreeViewItem_OnItemSelected"?我正在尝试基于TreeView创建一个新的控件,并希望在内部处理它,而不是在每个需要TreeView的地方进行处理。但是我似乎找不到可以通过TreeViewItem命名空间附加事件的地方... - user1618054
你可以在控件的构造函数中这样做:AddHandler(TreeViewItem.SelectedEvent, new RoutedEventHandler(TreeViewItem_Selected)); private void TreeViewItem_Selected(object sender, RoutedEventArgs e) { _selectedTreeViewItem = e.OriginalSource as TreeViewItem; } - loreggia

1
我发现的最佳解决方案涉及一个简单的辅助方法,并且可以在TreeView的任何事件中使用(例如SelectedItemChanged,MouseLeftButtonUp等)。
TreeViewItem Item = TreeViewHelper.VisualUpwardSearch(e.OriginalSource as DependencyObject);

我正在使用多层次数据模板,这是我唯一有效的方法。现在,我能够基于TreeView创建一个新的控件,并且可以内部处理所有涉及所选项目的事件。
public static TreeViewItem VisualUpwardSearch(DependencyObject source)
{
    while (source != null && !(source is TreeViewItem)) source = System.Windows.Media.VisualTreeHelper.GetParent(source);
    return source as TreeViewItem;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接