【问题标题】:ObjectListView - TreeListView Auto TriStateCheckingObjectListView - TreeListView 自动 TriStateChecking
【发布时间】:2013-01-31 10:35:25
【问题描述】:

有没有人成功让三态复选框在 TreeListView 中正常工作,而不使用模型对象中的属性来存储检查状态?

因此,例如,检查一个节点。应检查其所有子代(和子代子代等),然后应根据其兄弟姐妹CheckStates 检查其所有父母/祖父母。

我尝试了几种方法,但每种方法都在 TreeListView 类中得到一个ArgumentOutOfRange/ArgumentException。这包括以下内容:

  • 将所有节点 CheckStates 存储在字典中并用作 CheckStateGetter 事件的查找
  • 当项目 CheckState 更改时递归调用函数(并确保在以编程方式更改 CheckStates 时忽略后续的 ItemCheck 事件)
  • 调用函数以确定直接子/父状态,并让 TreeListView 为每个受影响的节点触发 ItemChecked 事件。

我经常从以下函数中得到错误(在 TreeListView.cs 中):

  • GetNthItem()
  • GetChildren() - 然后在 GUI 中展开/折叠屏蔽
  • ProcessLButtonDown()

如果有人在这方面取得了成功,我会全力以赴。

【问题讨论】:

    标签: c# recursion objectlistview treelistview


    【解决方案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;
        }
    

    也许这至少可以解决您的一些问题。

    【讨论】:

    • 非常感谢,我自己也发现了这个问题,但是我将有问题的行更改为 if (br.CanExpand) br.FetchChildren();。您是否注意到此修改的任何副作用?尽管如此,它确实看起来是正确的 - 这不会修改导致所有问题的分支的 Expanded 属性:) +1 无论查看源代码(我应该早点完成!)
    • 据我所知,代码更改似乎没有造成任何副作用。与 ObjectListView 相比,TreeListView 有很多错误(我之前多次使用过,没有任何重大问题)。我花了一些时间寻找或多或少等效(免费)的替代品,但似乎什么都没有。即使遇到麻烦,它仍然是一个重要的组成部分。快乐编码...
    • 感谢 Rev1.0 - 我同意迄今为止最好的,但有点怪癖。
    【解决方案2】:

    “在项目 CheckState 更改时递归调用函数(并确保在以编程方式更改 CheckState 时忽略后续的 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
        }
    

    【讨论】:

    • 在这种情况下,您应该在 TreeListView.cs 中修复: public virtual IEnumerable Children { <...> set { <...> if (checkedness.HasValue && checkedness.Value == CheckState. Checked) //treeListView.SetObjectCheckedness(x, checkedness.Value); treeListView.SetObjectCheckednessHelper(x, checkedness.Value, 0); }} 只替换评论的内容
    猜你喜欢
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    相关资源
    最近更新 更多