0

所以我有一个树视图,我希望能够通过单击它来取消选择一个节点。

我正在扩展树视图类(还需要一些其他功能),但我遇到了一个小问题。

这是我正在使用的代码:

     protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
    {

        base.OnNodeMouseClick(e);
        if (this.SelectedNode == e.Node)
        {
            this.SelectedNode = null;
            selectedSame = true;
        }
    }


    protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
    {
        if (selectedSame)
        {
            selectedSame = false;
            base.OnBeforeSelect(e);
            e.Cancel = true;
        }
    }

在调用 e.cancel 之后会发生什么,它通过 OnBeforeSelect 循环返回,现在它是错误的,所以它然后选择它(撤消我刚刚所做的!)。

我把 selectedSame = false; 从 OnBeforeSelect 中取出并将其置于其他位置,但随后这部分将无限运行并且永不中断!

    if (selectedSame)
        {
            selectedSame = false;
            base.OnBeforeSelect(e);
            e.Cancel = true;
        }

还测试了:

    protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
    {

            base.OnBeforeSelect(e);
            e.Cancel = true;
    }

而且它也只是循环了无数次(如果我把它关闭它实际上完成了,但是如果我把它放回去并点击它会进入它的循环数百次)。

我想我真的不明白 e.Cancel 应该如何工作,因为它似乎一旦点击取消它就会立即跳回来,甚至没有完成那个调用。

任何建议将不胜感激:)

-赖特

编辑: - 更多信息

做了一个全新的项目,以确保我所参与的任何事件都不会导致这个问题。结果相同,但它确实让我发现至少它正在采取的步骤。当我设置“this.SelectedNode = null”时,它会触发 OnBeforeSelect,这会导致整个事情一开始就搞砸了。但是,如果我有一个按钮,当单击该按钮时,将树的 selectednode 设置为 null,则 OnBeforeSelect 永远不会发生。那么有什么区别呢?

最后:

扩展类中除此之外没有代码:

    class StatedTreeView : System.Windows.Forms.TreeView
    {
    protected override void OnBeforeSelect(TreeViewCancelEventArgs e)
            {
            e.Cancel = true;            
            }
    }

如果你在取消上放一个中断......它只是循环和循环和循环。如果您取消中断,程序会变得有点可用(选择然后立即取消,这很好)。但是,如果您在它运行时添加中断,它会立即再次中断!您甚至不必选择节点!呃……我不明白

4

2 回答 2

1

这是调试器引起的工件。调试器试图尽可能地避开程序。但是让它在断点处中断有一些不可避免的副作用。这往往会使调试 UI 事件变得困难。例如,Paint 事件处理程序往往很棘手。

这里的问题是焦点发生了变化,从您的程序到 Visual Studio。并且您将 TreeView.HideSelection 属性设置为 True。所以焦点变化实际上取消了当前树节点的选择。当您恢复执行时,焦点会回到 TreeView 并再次选择节点。这会再次触发 OnBeforeSelect() 方法。这会再次触发断点,等等,等等。

在极端情况下,您可能需要使用远程调试器来克服这些副作用。但是您不必走那么远,因为您的代码很好。将 HideSelection 设置为 false 可以修复它,以防您需要继续调试它。

于 2013-01-17T22:47:58.463 回答
0

因为你一次又一次地调用OnBeforeSelect事件?您在没有任何停止条件的情况下递归调用事件(因为e.Cancel = true;在调用事件之后)

你确定需要打电话base.OnBeforeSelect吗?如果是这样,你可能想e.Cancel = true;先打电话。

于 2013-01-17T19:26:08.937 回答