2013-02-15 24 views
1

有沒有人已經成功地獲得三態複選框在TreeListView中正常工作,而不使用模型對象中的屬性來存儲Checkstate?ObjectListView - TreeListView自動TriStateChecking

因此,例如,一個節點被檢查。所有的孩子(以及兒童孩子等)都應該被檢查,然後所有的父母/祖父母應該根據其兄弟姐妹CheckStates進行檢查。

我嘗試了幾種方法,但每種方法都可以在TreeListView類中獲得ArgumentOutOfRange/ArgumentException。這包括以下內容:

  • 在字典中存儲的所有節點CheckStates和使用作爲查找與CheckStateGetter事件
  • 遞歸調用函數時的項目CheckState變化(並確保後續ItemCheck事件而編程忽略更改CheckStates
  • 調用一個函數來確定直接的子/父狀態,並讓TreeListView觸發每個受影響節點的ItemChecked事件。

我不斷地從下面的函數錯誤(TreeListView.cs):

  • GetNthItem()
  • 的GetChildren() - 然後展開/摺疊的shild在GUI
  • ProcessLButtonDown()

如果有任何人在這方面取得了成功,我會全力以赴。

回答

1

我也有一些TreeListView的問題,並在GetChildren()函數中發現問題。

GetChildren不必要地試圖擴大相關分支來獲取孩子。這導致內部狀態顯示爲展開,而視圖仍然崩潰並導致內部索引問題。

原始的方法:

public virtual IEnumerable GetChildren(Object model) { 
     Branch br = this.TreeModel.GetBranch(model); 
     if (br == null || !br.CanExpand) 
      return new ArrayList(); 

     if (!br.IsExpanded) // THIS IS THE PROBLEM 
      br.Expand(); 

     return br.Children; 
    } 

固定方法:

public virtual IEnumerable GetChildren(Object model) { 
     Branch br = this.TreeModel.GetBranch(model); 
     if (br == null || !br.CanExpand) 
      return new ArrayList(); 

     br.FetchChildren(); 

     return br.Children; 
    } 

也許這至少解決了你的一些問題。

+1

非常感謝,我才發現這個問題我自己,但是我改了行的問題1如果'(br.CanExpand)br.FetchChildren();'。你有沒有注意到這種修改的副作用?它確實看起來是正確的 - 但這不會修改引起所有問題的分支的'Expanded'屬性:) +1無論是否查看源代碼(我應該早一點做!) – Simon 2013-02-15 14:34:05

+0

代碼更改據我所知,似乎沒有引起任何副作用。與ObjectListView(我之前使用過很多次,沒有任何重大問題)相比,TreeListView相當麻煩。我花了一些時間尋找一個或多或少的同等(免費)替代品,但似乎沒有任何東西在那裏。即使遇到麻煩,它仍然是一個很好的組成部分。快樂編碼... – 2013-02-15 14:45:13

+0

謝謝Rev1.0 - 我同意迄今爲止最好的,但有點怪癖。 – Simon 2013-02-15 14:46:43

0

「遞歸調用函數時的項目CheckState變化(並確保後續ItemCheck事件,而編程改變CheckStates被忽略)」

如果TreeListView自檢(「從箱」)是對你有好處,你只是想知道當你手動完成一些主要複選框點擊後所有人員完成 (這意味着:你點擊,TreeListView(聯合國)檢查所有兒童和父母), ,所以你需要在ObjectListView圖書館(粗略):

\ objectlistviewdemo \ objectlistview \ treelistview。CS

首先添加事件(我的事件是不好的,但你知道要解決什麼)

#region Events 

    public delegate void AfterTreeCheckEventHandler(object sender/*, object rowmodel*/); 

    /// <summary> 
    /// Triggered when clicked main checkbox checked and all related too. 
    /// </summary> 
    [Category("ObjectListView"), 
    Description("This event is triggered when clicked main checkbox checked and all related too.")] 
    public event AfterTreeCheckEventHandler AfterTreeCheckAndRecalculate; 

    #endregion 

    #region OnEvents 

    /// <summary> 
    /// Tell the world when a cell has finished being edited. 
    /// </summary> 
    protected virtual void OnAfterTreeCheckAndRecalculate(/*CellEditEventArgs e*/) 
    { 
     if (this.AfterTreeCheckAndRecalculate != null) 
      this.AfterTreeCheckAndRecalculate(this/*, e*/); 
    } 

    #endregion 

其次,你需要修復「SetObjectCheckedness」方法

(1種1個簡單+ 1個遞歸遞歸方法)
 /// <summary> 
    /// Change the check state of the given object to be the given state. 
    /// </summary> 
    /// <remarks> 
    /// If the given model object isn't in the list, we still try to remember 
    /// its state, in case it is referenced in the future.</remarks> 
    /// <param name="modelObject"></param> 
    /// <param name="state"></param> 
    /// <returns>True if the checkedness of the model changed</returns> 
    protected override bool SetObjectCheckedness(object modelObject, CheckState state) { 
     // If the checkedness of the given model changes AND this tree has 
     // hierarchical checkboxes, then we need to update the checkedness of 
     // its children, and recalculate the checkedness of the parent (recursively) 

     bool result = SetObjectCheckednessHelper(modelObject, state, 0); 

     if (this.AfterTreeCheckAndRecalculate != null) 
      this.AfterTreeCheckAndRecalculate(this); //report that work is done 
     return result; 
    } 

    protected bool SetObjectCheckednessHelper(object modelObject, CheckState state, int i) //recursive 
    { 
     if (!base.SetObjectCheckedness(modelObject, state)) 
      return false; 

     if (!this.HierarchicalCheckboxes) 
      return true; 

     // Give each child the same checkedness as the model 

     CheckState? checkedness = this.GetCheckState(modelObject); 
     if (!checkedness.HasValue || checkedness.Value == CheckState.Indeterminate) 
      return true; 

     foreach (object child in this.GetChildrenWithoutExpanding(modelObject)) 
     { 
      this.SetObjectCheckednessHelper(child, checkedness.Value, i+1); 
     } //(un)check all children checkboxes 

     if (i == 0) //recalculate upper levels only in the case of first call 
     { 
      ArrayList args = new ArrayList(); 
      args.Add(modelObject); 
      this.RecalculateHierarchicalCheckBoxGraph(args); //all upper checkboxes in intermediate state or (un)check 
     } 

     return true; 
    } 

用法:

this.olvDataTree.AfterTreeCheckAndRecalculate += new BrightIdeasSoftware.TreeListView.AfterTreeCheckEventHandler(this.olvDataTree_TreeChecked); 

    private void olvDataTree_TreeChecked(object sender) 
    { 
      //some staff here 
    } 
+0

加上在這種情況下,你應該在TreeListView.cs修復: 公共虛擬IEnumerable的兒童{ <...> 集合{ <...> 如果(checkedness.HasValue && checkedness.Value == CheckState.Checked) //treeListView.SetObjectCheckedness( x,checkedness.Value); treeListView.SetObjectCheckednessHelper(x,checkedness.Value,0); }} 只是取代所發表的評論 – 2016-10-21 21:16:11