如何禁用树节点复选框?

Posted

技术标签:

【中文标题】如何禁用树节点复选框?【英文标题】:How can I disable a treenode checkbox? 【发布时间】:2021-05-18 05:24:17 【问题描述】:

我正在使用 codeproject 中的 treeviewExtensions,它实现了一些 iEnumerable 递归,以便在检查节点时检查所有父节点和子节点。

接下来我想实现一种禁用特定节点的方法。我已通过 GUI 将颜色设置为灰色来指示节点不可用。但是,节点旁边的复选框仍然是启用的,并且没有禁用/启用属性。有什么办法可以解决这个问题?

【问题讨论】:

Prevent user from altering Check boxes in TreeView 作为替代方案,您可以使用TVITEMEX 结构,设置hItem = [TreeNode].Handlemask = TVIF_STATEEXstateMask = TVIS_STATEIMAGEMASKuStateEx = TVIS_EX_DISABLED。然后SendMessage([TreeView].Handle, TVM_SETITEM, IntPtr.Zero, ref yourTviExStruct); 替代或补充,这取决于您要如何处理。 【参考方案1】:

如果 TreeNode 被禁用,您没有明确指定您想要什么。你只想要一些特殊的颜色,或者如果 TreeNode 被禁用,你想要一些带有 Checked 状态和子节点的东西?

所以你想要一个有一些特殊行为的 TreeNode?​​p>

在您的 OO 课程中,您了解到,如果您想要与其他东西具有几乎相同行为的东西,您应该考虑从另一个派生。

class TreeNodeThatCanBeDisabled : TreeNode // TODO: invent proper name

    // Coloring when enabled / disabled
    public Color EnabledForeColor get; set; = base.ForeColor;
    public Color EnabledBackColor get; set; = base.BackColor;
    public Color DisabledForeColor get; set; = ...
    public Color DisabledBackColor get; set; = ...

    private bool isEnabled = true;

    public bool IsEnabled
    
        get => this.isEnable;
        set
        
            it (this.IsEnabled = value)
            
                // TODO: set the colors
                this.isEnabled = value;
            
        
    

也许您想在 IsEnabled 更改时引发事件,我不确定每个节点执行此操作是否明智:

public event EventHandler IsEnabledChanged;
protected virtual void OnEnabledChanged(EventHandle e)

    this.IsEnabledChanged?.Invoke(this, e);

在 IsEnabled Set 中调用它。

此外:复选标记的用途是什么?并且所有子节点也应该被禁用吗?

foreach (TreeNodeThatCanBeDisabled subNode in this.Nodes.OfType<TreeNodeThatCanBeDisabled())

    subNode.IsEnabled = value;

而且我认为您应该创建一个 TreeNodeView,它可以一次启用/禁用多个 TreeNode,并且可以为您提供所有启用/禁用的节点。

TODO:决定这个特殊的 TreeNodeView 是否可能只包含 TreeNodesThatCanBeDisabled,或者也包含标准 TreeNodes。

class TreeNodeViewThatCanHoldTreeNodesThatCanBeDisabled : TreeNodeView // TODO: proper name

    // Coloring when enabled / disabled
    public Color EnabledForeColor get; set; = base.ForeColor;
    public Color EnabledBackColor get; set; = base.BackColor;
    public Color DisabledForeColor get; set; = ...
    public Color DisabledBackColor get; set; = ...

    public void AddNode(TreeNodeThatCanBeDisabled treeNode)
    
        this.Nodes.Add(treeNode);
    

    public IEnumerable<TreeNodeThatCanBeDisabled> TreeNodesThatCanBeDisabled =>
        base.Nodes.OfType<TreeNodeThatCanBeDisabled>();

    public IEnumerable<TreeNodeThatCanBeDisabled> DisabledNodes =>
        this.TreeNodesThatCanBeDisabled.Where(node => !node.IsEnabled);

    public void DisableAll()
    
        foreach (var treeNode in this.TreeNodesThatCanBeDisabled)
            treeNode.Enabled = false;
    

TODO:你只想改变颜色吗?还是复选框?折叠/展开? 也许是一个事件告诉你:“嘿,伙计,这个 treeNode 已被禁用”?

如果有人点击禁用的 TreeNode 会怎样。它应该仍然折叠/展开,还是应该保持它的状态:

protected override void OnBeforeExpand (System.Windows.Forms.TreeViewCancelEventArgs e)

    if (e.Node is TreeNodeThatCanBeDisabled treeNode)
    
        // cancel expand if not enabled:
        if (!treeNode.IsEnabled)
           e.Cancel = true;
    

类似的崩溃?

【讨论】:

以上是关于如何禁用树节点复选框?的主要内容,如果未能解决你的问题,请参考以下文章

当我取消选中自定义树视图中的子节点复选框时,如何取消选中所有父节点

如何使用wpf中的复选框开发树视图?

如何包含特定 TreeView 节点的复选框?

如何将复选框添加到 JTree 节点以管理多选?

elementui中el-tree实现复选框全部禁用

elementui中el-tree实现复选框全部禁用