如何从HierarchicalDataTemplate项中获取TreeViewItem?

Raz*_*zie 31 wpf treeview hierarchicaldatatemplate

我有一个TreeView使用a HierarchicalDataTemplate绑定其数据.

它看起来像这样:

<TreeView x:Name="mainTreeList" ItemsSource="{Binding MyCollection}>
  <TreeView.Resources>
    <HierarchicalDataTemplate 
     DataType="{x:Type local:MyTreeViewItemViewModel}" 
     ItemsSource="{Binding Children}">
      <!-- code code code -->
    </HierarchicalDataTemplate>
  </TreeView.Resources>
</TreeView>
Run Code Online (Sandbox Code Playgroud)

现在,从主窗口的代码隐藏,我想得到当前选择TreeViewItem.但是,如果我使用:

this.mainTreeList.SelectedItem;
Run Code Online (Sandbox Code Playgroud)

selectedItem属于类型MyTreeViewItemViewModel.但我想得到'父母'或'约束' TreeViewItem.我没有把它传递给我的TreeViewItemModel对象(甚至不知道如何).

我怎样才能做到这一点?

mar*_*mnl 31

TreeViewItem item = (TreeViewItem)(mainTreeList
    .ItemContainerGenerator
    .ContainerFromIndex(mainTreeList.Items.CurrentPosition));
Run Code Online (Sandbox Code Playgroud)

不使用(对我来说)作为使用HierarchicalDataTemplate的树视图中的mainTreeList.Items.CurrentPosition将始终为-1.

同样没有下文如为mainTreeList.Items.CurrentItem在使用HierarchicalDataTemplate永远是空树视图.

TreeViewItem item = (TreeViewItem)mainTreeList
    .ItemContainerGenerator
    .ContainerFromItem(mainTreeList.Items.CurrentItem);
Run Code Online (Sandbox Code Playgroud)

INSTEAD我必须在路由的TreeViewItem.Selected事件中设置最后一个选定的TreeViewItem,它会冒泡到树视图(TreeViewItem本身在设计时不存在,因为我们使用的是HierarchicalDataTemplate).

事件可以在XAML中捕获,如下所示:

<TreeView TreeViewItem.Selected="TreeViewItemSelected" .../> 
Run Code Online (Sandbox Code Playgroud)

然后可以在事件中设置最后选择的TreeViewItem,如下所示:

    private void TreeViewItemSelected(object sender, RoutedEventArgs e)
    {
        TreeViewItem tvi = e.OriginalSource as TreeViewItem;

        // set the last tree view item selected variable which may be used elsewhere as there is no other way I have found to obtain the TreeViewItem container (may be null)
        this.lastSelectedTreeViewItem = tvi;

        ...
     }
Run Code Online (Sandbox Code Playgroud)

  • 我认为你使用的mainTreeList.Items问题只适用于树视图第一层中的项目 - 每个树视图节点(TreeViewItem)都有自己的Items集合 - 不像Bea的例子,你引用的是使用ListBox和只有一个级别的项目.接下来你需要获得当前选择的TreeViewItem的引用,我在使用HierarchicalDataTemplate时找到的唯一方法就是在我的回答中捕获TreeViewItem.Selected事件. (2认同)

Cam*_*and 21

Bea Stollnitz关于此的博客文章中试试

TreeViewItem item = (TreeViewItem)(mainTreeList
    .ItemContainerGenerator
    .ContainerFromIndex(mainTreeList.Items.CurrentPosition));
Run Code Online (Sandbox Code Playgroud)

  • 无论选择什么,对我来说,'CurrentPosition`始终为0.您链接到的博客条目是关于列表,而不是树 - 也许这就是原因.链接的博客文章中没有涉及"HierarchicalDataTemplate". (7认同)

san*_*oIT 7

我遇到了同样的问题.我需要访问TreeViewItem,以便我可以选择它.然后我意识到我可以在我的ViewModel中添加一个属性IsSelected,然后将其绑定到TreeViewItems IsSelectedProperty.这可以通过ItemContainerStyle实现:

<TreeView>
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                </Style>
            </TreeView.ItemContainerStyle>
</TreeView>
Run Code Online (Sandbox Code Playgroud)

现在,如果我想在树视图中选择一个项目,我只需直接在我的ViewModel类上调用IsSelected.

希望它可以帮助某人.

  • 在我看来,这是使用树视图的最佳方式.项目_need_是viewmodels,因此您可以使用它们属性.否则你最终不得不做各种各样的恶作剧,以获得应该是简单的行为才能正常工作. (2认同)

小智 5

TreeViewItem item = (TreeViewItem)(mainTreeList
    .ItemContainerGenerator
    .ContainerFromIndex(mainTreeList.Items.CurrentPosition)); gives first item in the TreeView because CurrentPosition is always 0.
Run Code Online (Sandbox Code Playgroud)

怎么样

TreeViewItem item = (TreeViewItem)(mainTreeList
    .ItemContainerGenerator
    .ContainerFromItem(mainTreeList.SelectedItem)));
Run Code Online (Sandbox Code Playgroud)

这对我来说效果更好.