WPF TreeView 清除选择

问题描述 投票:0回答:10

如何清除 WPF TreeView 中的 TreeView 选择?我尝试循环遍历

TreeNodes
并清除
IsSelected
属性,但这是一个
ReadOnly
属性。有什么想法吗?

TreeView
通过
XMLDataProvider
对象使用 XML 绑定。

.net wpf treeview
10个回答
13
投票

我遇到了完全相同的问题,并编写了以下代码,该代码适用于任何树视图,只需对第一个函数进行单行调用。

class TomWrightsUtils
{
    public static void ClearTreeViewSelection(TreeView tv)
    {
        if (tv != null)
            ClearTreeViewItemsControlSelection(tv.Items, tv.ItemContainerGenerator);
    }
    private static void ClearTreeViewItemsControlSelection(ItemCollection ic, ItemContainerGenerator icg)
    {
        if ((ic != null) && (icg != null))
            for (int i = 0; i < ic.Count; i++)
            {
                TreeViewItem tvi = icg.ContainerFromIndex(i) as TreeViewItem;
                if (tvi != null)
                {
                    ClearTreeViewItemsControlSelection(tvi.Items, tvi.ItemContainerGenerator);
                    tvi.IsSelected = false;
                }
            }
    }
}

8
投票

不确定您所说的 TreeNode 是什么意思。

通常,您的视图绑定到的视图模型上会有相应的

IsSelected
属性:

<TreeView>
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

因此,您只需循环访问视图模型中的数据项并在那里设置

IsSelected = false

但是,听起来你没有这样的财产。既然如此,就需要为每个数据项获取对应的

TreeViewItem
。有关如何执行此操作的信息,请参阅
TreeView.ItemContainerGenerator
属性。比如:

var treeViewItem = _treeView.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;
treeViewItem.IsSelected = false;

6
投票
TreeViewItem tvi = tvMain.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;

if (tvi != null) { tvi.IsSelected = true; tvi.IsSelected = false; }

2
投票

找到选中的项目并设置值:

private void Button_Click(object sender, RoutedEventArgs e)
{
  TreeViewItem tvi = treeviewExample.SelectedItem as TreeViewItem;
  if (tvi != null)
  {
    tvi.IsSelected = false;
  }
}

2
投票

这作为扩展方法非常有效,因此您可以调用

youTreeview.ClearSelection();

using System.Windows.Forms;
using System.Windows.Controls;

namespace YourAppNamespace
{
    public static void ClearSelection(this TreeView input)
    {
    // this should be some container that you put in
    // possibly the actual treeviewitem, not sure on that though
    var selected = input.SelectedItem;
    if (selected == null)
        return;

    // in my case this works perfectly
    var tvi = input.ItemContainerGenerator.ContainerFromItem(selected) as TreeViewItem;
    var tvi = input.ItemContainerGenerator.ContainerFromItem(selected) as TreeViewItem;
    if (tvi == null)
    {
        // it must be a child, heres a hack fix
        // my nodes are inherited from TreeViewItemViewModel by Josh Smith
        var child = selected as WPF.Controls.TreeViewItemViewModel;
        if (child == null)
            return;
        child.IsSelected = false;

    }
    else
        tvi.IsSelected = false;
     }


}

1
投票

我的经验是远离标准 ItemContainerGenerator 调用,因为它们会在深度大于 n+1 的节点上失败。我使用以下扩展方法的组合。 ContainerFromItem 扩展方法来自 MSDN 博客,它在处理 TreeView 时为我创造了奇迹。

  public static void ClearSelection(this TreeView input)
  {
     var selected = input.SelectedItem;

     if (selected == null) return;

     var tvi = input.ContainerFromItem(selected) as TreeViewItem;

     if (tvi == null) return;

     tvi.IsSelected = false;

  }

  public static TreeViewItem ContainerFromItem(this TreeView treeView, object item)
  {
     TreeViewItem containerThatMightContainItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(item);
     if (containerThatMightContainItem != null)
        return containerThatMightContainItem;
     else
        return ContainerFromItem(treeView.ItemContainerGenerator, treeView.Items, item);
  }

  private static TreeViewItem ContainerFromItem(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection, object item)
  {
     foreach (object curChildItem in itemCollection)
     {
        TreeViewItem parentContainer = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem);
        if (parentContainer == null)
           return null;
        TreeViewItem containerThatMightContainItem = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(item);
        if (containerThatMightContainItem != null)
           return containerThatMightContainItem;
        TreeViewItem recursionResult = ContainerFromItem(parentContainer.ItemContainerGenerator, parentContainer.Items, item);
        if (recursionResult != null)
           return recursionResult;
     }
     return null;
  }

0
投票

到目前为止,这似乎有效,但我只是在 5 分钟前将其放入,因此使用风险自负。我基本上想在用户单击树控件内而不是树项目时清除选择。

 void DestinationTree_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
     TreeView tree = sender as TreeView;
     DestinationClientViewModel selectedItem = tree.SelectedItem as DestinationClientViewModel;

     if (selectedItem != null)
     {
        int selectedItemIndex = this.DestinationTree.Items.IndexOf(selectedItem);

        if (selectedItemIndex > -1)
        {
            TreeViewItem tvi = this.DestinationTree.ItemContainerGenerator.ContainerFromIndex(selectedItemIndex) as TreeViewItem;
            if (tvi != null)
                tvi.IsSelected = false;
        }
     }
 }

0
投票

我自己在使用自定义树列表视图实现时遇到了这种情况,经过很长时间的寻找,我终于找到了一个适合我的解决方案。

完整说明可在 http://social.msdn.microsoft.com/Forums/vstudio/en-US/36aca7f7-0b47-488b-8e16-840b86addfa3/getting-treeviewitem-for-the-selected-item 找到-树视图

基本思想是捕获

TreeViewItem.Selected
事件并将事件源保存到 TreeView 上的
Tag
属性中。然后,当您需要清除它时,可以访问控件上的
Tag
属性并将
IsSelected
值设置为 False。这对我来说适用于两层嵌套的孩子。希望它对你有用。

为了坚持:

TreeView声明

  <TreeView Name="myTreeView" TreeViewItem.Selected="OnItemSelected"
    ItemsSource="{Binding Source={StaticResource myHierarchicalData}}"/>

事件处理程序

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

清晰的选择逻辑

if (myTreeView.SelectedItem != null)
{
    TreeViewItem selectedTVI = myTreeView.Tag as TreeViewItem;
    // add your code here mine was selectedTVI.IsSelected = false;
}

0
投票

我刚刚遇到了同样的问题。

快速但肮脏的解决方案

tree.ItemsSource = null;

tree.ItemsSource = yourSource;

0
投票

这对我来说非常完美

var tvi = CurvesTree.ItemContainerGenerator.ContainerFromItem(CurvesTree.SelectedItem) as TreeViewItem;

if (tvi is null)
    return;

tvi.IsSelected = false;
© www.soinside.com 2019 - 2024. All rights reserved.