1

チェックステートを格納するためにモデル オブジェクトのプロパティを使用せずに、TreeListView で正しく動作するトライステート チェックボックスを正常に取得した人はいますか?

たとえば、ノードがチェックされます。すべての子 (および子の子など) をチェックしてから、兄弟に従ってすべての親/祖父母をチェックする必要がありますCheckStates

いくつかの方法を試しましたが、いずれの方法でも TreeListView クラス内でArgumentOutOfRange/を取得します。ArgumentExceptionこれには以下が含まれます。

  • すべてのノード CheckStates をディクショナリに格納し、CheckStateGetterイベントでルックアップとして使用する
  • 項目が変更されたときに関数を再帰的に呼び出すCheckState(そして、プログラムによる変更中に後続の ItemCheck イベントが確実に無視されるようにするCheckStates)
  • ItemChecked関数を呼び出して直接の子/親の状態を決定し、影響を受けるノードごとにTreeListView にイベントを発生させます。

次の関数 (TreeListView.cs 内) から常にエラーが発生します。

  • GetNthItem()
  • GetChildren() - GUI でシールドを展開/折りたたむ
  • ProcessLButtonDown()

誰かがこれで成功した場合、私はすべて耳にします。

4

2 に答える 2

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;
    }

多分これはあなたの問題の少なくともいくつかを解決します.

于 2013-02-15T14:14:36.263 に答える
0

「項目の CheckState が変更されたときに関数を再帰的に呼び出す (およびプログラムで CheckStates を変更している間、後続の ItemCheck イベントが確実に無視されるようにする)」

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 つの再帰メソッド)。

        /// <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
    }
于 2016-10-20T20:41:59.100 に答える