2013-01-17 48 views
0

所以我有一个树形视图,我想通过单击它可以取消选择一个节点。为什么TreeView.OnBeforeSelect循环?

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

这是我的工作代码:

 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是如何工作的,因为它尽快好像因为它击中取消跳右后卫周围甚至没有完成这一呼吁。

任何意见将非常感激:)

-Wright

编辑: - 更多信息

做了一个全新的项目,以确保没有,我就迷上了这些事件均引起这个问题。同样的结果,但它确实让我发现至少它正在采取的步骤。当我设置“this.SelectedNode = null”时,它会触发OnBeforeSelect,它会导致整个事情首先陷入混乱。但是,如果我有一个按钮,单击它时将树的selectednode设置为null,OnBeforeSelect从不发生。那有什么区别?

决赛:

在这以外扩展类无代码:

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

如果你把休息的取消......它只是循环和循环和循环。如果你休息一下,程序变得有些可用(选择然后立即取消,这很好)。但是,如果您在运行时添加折返,它会立即再次折断!你甚至不必选择一个节点!呃......因为你保持连连呼叫OnBeforeSelect事件我没有得到这个

回答

1

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

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

在极端情况下,您可能需要使用远程调试器才能消除这些副作用。但是你不必走得太远,因为你的代码是好的。将HideSelection设置为false可以修复它,以防您需要继续调试。

+0

这可能是问题的一部分。但是我在另一个关于HideSelection = false的论坛上读过。并且已经有了这整个时间。它仍然会做永不结束的取消循环。但它可能仍然是调试器本身造成的。虽然这并不能真正解释为什么如果我把它取下来,那么只要将它放回即可立即捕捉它。 – Wrightboy

+0

那么,在该方法中添加一个Console.WriteLine(),这样您就可以在Output窗口中看到这个报告,而不必使用调试器断点。我以这种方式测试了您的第一个代码片段,并没有发现递归问题。 –

+0

这实际上似乎是问题所在。我在OnNodeMouseClick()方法内部移动了所有的逻辑,以便在触发主窗体捕获的事件(NodeClicked)之前执行操作,并且只需要使用OnBefore内的取消布尔即可取消它。似乎运作良好! 谢谢! – Wrightboy

0

?你是递归调用事件没有任何停止条件(因为e.Cancel = true;调用事件之后)。

您确实需要调用base.OnBeforeSelect?如果是这样的话,你可能要先拨打e.Cancel = true;

+0

对不起,我离开了那部分。我实际上只用e.Cancel尝试过,但它只是无限循环... if(selectedTwiceRemove) { e.Cancel = true; } 我不知道是什么使它调用OnBeforeSelect一遍又一遍甚至是取消。我只是想让它停下来! – Wrightboy