实际上取消选择TreeView中的所有节点(.NET)

3

我试图取消 TreeView 中所有节点的选择。所谓的“真正取消选择”是指 TreeView1.SelectedNode = null; 会实际取消树中的节点。

目前,从视觉上看,该节点已被取消选择。但是,当我尝试添加新节点时,treeview 会自动选择树中的第一个节点(位于顶部)并创建子节点,而我理想情况下要创建父节点。在添加之前,我也不能仅取消选择选定的节点,因为用户可能想要添加子节点。我希望的行为是基于 TreeView 中选定的内容来添加父/子节点。如果没有选定任何内容,则添加父节点;如果选定了内容,则在选定的节点中添加子节点。

我在函数中构建了名为 node 的 TreeNode 对象,并具有图像和文本等内容,然后我有以下内容:

        if (tvContent.SelectedNode == null)
            tvContent.Nodes.Add(node);
        else
        {
            tvContent.SelectedNode.Nodes.Add(node);
            tvContent.SelectedNode.Expand();
        }

我有一个“取消选择全部”按钮,它应该使上面的代码工作。该按钮的代码很简单:

tvContent.SelectedNode = null;

请见谅我同时标记了C#和VB.NET。我两种语言都很熟悉,所以如果有人能帮我解决其中一种语言的问题那就太棒了!

谢谢

编辑: 有趣的是,在测试所选节点是否为null时,.NET会自动将所选节点设置为树中的第一个节点。下面的代码显示了"trigger"消息框,但在if语句完成后立即选择树中的第一个节点。

    private void btnDeselectAll_Click(object sender, EventArgs e)
    {
        tvContent.SelectedNode = null;
        if (tvContent.SelectedNode == null) MessageBox.Show("trigger");
    }

编辑2:问题在于使用InputBox作为节点标题输入的工具。由于某种原因,这会更改树形视图中所选节点。我在一个普通项目中尝试了一下,并成功地复制了该问题。我想这是无法解决的:S


在tvContent.SelectedNode的代码块上设置一个断点,然后使用F11(逐步调试)查看哪一行代码将tvContent.SelectedNode更改为第一个节点。 - Martheen
没有找到任何改变它的代码,它看起来像是自己在改变。 - Dan
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Dan
@Martheen,请查看我的帖子的“EDIT2”。有什么想法吗? - Dan
你使用InputBox进行标题输入是什么意思?最好直接发布你的存储库,这样我们就可以复制这个问题。 - Martheen
电视必须始终有一个选定节点。它具有双重功能,不仅显示所选节点,而且还表明电视具有焦点。您无法隐藏后者。不太清楚为什么这是个问题,只需确保始终有根节点即可。 - Hans Passant
3个回答

1
所以事实证明,无法实现“真正”的取消选择。一旦树形视图失去焦点,然后再次获得焦点(例如通过弹出的输入框窗口),所选节点将不再为空。
我的解决方法是引入一个面板,在主表单上显示一些输入选项,以便在主表单上完成节点标题输入,而不是在另一个表单上进行。我不喜欢这个修复方法,但这是唯一可以做的。

0

这对我有用

Private LastSelectetNode As TreeNode

Protected Overrides Sub OnBeforeSelect(e As TreeViewCancelEventArgs)
    e.Cancel = LastSelectetNode Is Nothing  
    MyBase.OnBeforeSelect(e)
End Sub

Protected Overrides Sub OnMouseUp(e As MouseEventArgs)
    Dim nd = MyBase.HitTest(e.Location).Node
    If LastSelectetNode Is nd Then
        SelectedNode = Nothing
        LastSelectetNode = Nothing
    Else
        LastSelectetNode = nd
    End If
    MyBase.OnMouseUp(e)
End Sub

-1

我试图复现你的场景,但失败了。在将 SelectedNode 设置为 null 后,当我尝试读取它时,它仍然是 null。有几件事我想要检查:

  1. 你确定你确实取消选中了节点吗?如果 TreeView 的 "HideSelection" 属性设置为 True(默认值),那么每当 TreeView 失去焦点时(比如当你点击取消全部选择按钮时),选中状态都会消失,使它看起来像是正常工作的。通过将 HideSelection 设置为 False 来确保这不是问题所在。

  2. 你确定你没有在将 SelectedNode 设置为 null 时触发事件处理程序(比如 SelectedNodeChanged)吗?


2
这是作为一个回答发布的,但它并没有试图回答问题。它可能应该是一个编辑、评论、另一个问题或完全删除。 - Trevor
嘿,谢谢你的回复!
  1. HideSelection设置为true,但更改后仍然出现相同的问题。
  2. 据我所知,在将选定节点设置为null之后,不会触发任何事件,甚至没有"AfterSelect"事件。
我进行了深入的调试,看起来树形视图在添加新节点时拒绝不选择一个节点。我的当前解决方案是,在添加新节点之前设置某种标志,确定首先选择了另一个节点。
- Dan
我的帖子中的“EDIT2”提供了一种复制该问题的方法。我不知道如何修复这样的问题:S - Dan

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