2013-01-17 76 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