如何显示在C#一个TreeView多个复选框? [英] How to show multiple check boxes in a TreeView in C#?

查看:151
本文介绍了如何显示在C#一个TreeView多个复选框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何显示在一个TreeView每个树节点一个复选框。
我想显示3复选框TreeView中的每一个树节点。
这样做的理由是,有在我的节目3的图表,并且每个树节点代表不同的系列。我想给用户显示他们喜欢的任何图表每个系列的选项。

I know how to show a single CheckBox for each TreeNode in a TreeView. I would like to show 3 CheckBoxes for each TreeNode in a TreeView. The reason for this is that there are 3 charts in my program, and each TreeNode represents a different series. I would like to give the user the option of displaying each series on whichever chart they like.

这是(或类似的东西)可能吗?先谢谢了。

Is this (or something similar) possible? Thanks in advance.

推荐答案

您将需要业主画出 TreeView控件。不完全是最简单的例子所有者绘制控制,但仍然不是太难。

You will need to owner-draw a TreeView. Not exactly the simplest example of owner-drawing a Control but still not too hard.

下面是一个例子截图:

首先,我们创建简单的树节点子持有额外的数据:

First we create simple TreeNode subclass to hold the extra data:

public class TreeNode3 : TreeNode
{
    public string Label { get; set; }
    public bool Check1 { get; set; }
    public bool Check2 { get; set; }
    public bool Check3 { get; set; }

    public new string Text
    {
        get { return Label; }
        set { Label = value; base.Text = ""; }
    }

    public TreeNode3()   { }

    public TreeNode3(string text)   { Label = text; }

    public TreeNode3(string text, bool check1, bool check2, bool check3)
    {
        Label = text;
        Check1 = check1; Check2 = check2; Check3 = check3;
    }

    public TreeNode3(string text, TreeNode3[] children)
    {
        Label = text;
        foreach (TreeNode3 node in children) this.Nodes.Add(node);
    }
}

请注意,我隐藏原始文本,基本上取代它通过一个字符串变量标签。我避免使用标签所以你仍然可以利用它自己。我还没有实现所有构造函数。如果你需要图像列表你可能要添加这些与 ImageIndices

Note that I hide the original Text and basically replace it by a string variable Label. I avoid using the Tag so you can still make use of it yourself.. I have not implemented all constructors. If you need ImageLists you may want to add those with the ImageIndices.

现在的 TreeView控件本身:

using System.Windows.Forms.VisualStyles;
//..

public partial class UcTreeView : TreeView
{
    [DisplayName("Checkbox Spacing"),  CategoryAttribute("Appearance"),
     Description("Number of pixels between the checkboxes.")]
    public int Spacing { get; set; }

    [DisplayName("Text Padding"), CategoryAttribute("Appearance"), 
     Description("Left padding of text.")]
    public int LeftPadding { get; set; }



    public UcTreeView()
    {
        InitializeComponent();
        DrawMode = TreeViewDrawMode.OwnerDrawText;
        HideSelection = false;    // I like that better
        CheckBoxes = false;       // necessary!
        FullRowSelect = false;    // necessary!
        Spacing = 4;              // default checkbox spacing
        LeftPadding = 7;          // default text padding
    }

    public TreeNode3 AddNode(string label, bool check1, bool check2, bool check3)
    {
        TreeNode3 node = new TreeNode3(label, check1, check2, check3);
        this.Nodes.Add(node);
        return node;
    }

    private  Size glyph = Size.Empty;

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        TreeNode3 n = e.Node as TreeNode3;
        if (n == null) { e.DrawDefault = true; return; }

        CheckBoxState cbsTrue = CheckBoxState.CheckedNormal;
        CheckBoxState cbsFalse = CheckBoxState.UncheckedNormal;

        Rectangle rect = new Rectangle(e.Bounds.Location, 
                             new Size(ClientSize.Width, e.Bounds.Height));
        glyph = CheckBoxRenderer.GetGlyphSize(e.Graphics, cbsTrue );
        int offset = glyph.Width * 3 + Spacing * 2 + LeftPadding;

        if (n.IsSelected)
        {
            e.Graphics.FillRectangle(SystemBrushes.MenuHighlight ,rect);
            e.Graphics.DrawString(n.Label, Font, Brushes.White, 
                                  e.Bounds.X + offset, e.Bounds.Y);
        }
        else
        {
            CheckBoxRenderer.DrawParentBackground(e.Graphics, e.Bounds, this);
            e.Graphics.DrawString(n.Label, Font, Brushes.Black, 
                                  e.Bounds.X + offset, e.Bounds.Y);
        }

        CheckBoxState bs1 = n.Check1 ? cbsTrue : cbsFalse;
        CheckBoxState bs2 = n.Check2 ? cbsTrue : cbsFalse;
        CheckBoxState bs3 = n.Check3 ? cbsTrue : cbsFalse;

        CheckBoxRenderer.DrawCheckBox(e.Graphics,  cbx(e.Bounds, 0).Location, bs1);
        CheckBoxRenderer.DrawCheckBox(e.Graphics,  cbx(e.Bounds, 1).Location, bs2);
        CheckBoxRenderer.DrawCheckBox(e.Graphics,  cbx(e.Bounds, 2).Location, bs3);

    }

    protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
    {
        Console.WriteLine(e.Location + " bounds:"  + e.Node.Bounds);

        TreeNode3 n = e.Node as TreeNode3;
        if (e == null) return;

        if      (cbx(n.Bounds, 0).Contains(e.Location)) n.Check1 = !n.Check1;
        else if (cbx(n.Bounds, 1).Contains(e.Location)) n.Check2 = !n.Check2;
        else if (cbx(n.Bounds, 2).Contains(e.Location)) n.Check3 = !n.Check3;
        else
        {
            if (SelectedNode == n && Control.ModifierKeys == Keys.Control)
                 SelectedNode = SelectedNode != null ? null : n;
            else SelectedNode = n;
        }

        Console.WriteLine(" " + n.Check1 + " " + n.Check2 +" " + n.Check3 );

        Invalidate();

    }


    Rectangle cbx(Rectangle bounds, int check)
    {
        return new Rectangle(bounds.Left + 2 + (glyph.Width + Spacing) * check, 
                             bounds.Y + 2, glyph.Width, glyph.Height);
    }

}



的几个注意事项:

A few notes:


  • 树不支持 LabelEditing 。可行的,但蠕虫另可..

  • 树不支持 FullrowSelect 是真实的,但实际上它是有效反正..

  • 您应该能够使用的ImageList StateImageList ,但需要设置节点后,指数增加。

  • 请不要在的CheckBox 属性设置为true!所有这三个的CheckBox 是虚拟的,你转换为 TreeNode3 检查1节点后访问它们..Check3 属性!

  • 我还没有实现三态的复选框。你可以改变的bool为可以为空,然后添加在点击所需的代码和借鉴的事件。

  • 我留下了几个 Console.WriteLines 中的代码进行更好的测试。

  • The tree does not support LabelEditing. Doable but another can of worms..
  • The tree does not support FullrowSelect to be true but actually it is in effect anyway..
  • You should be able to use ImageList and StateImageList but need to set the indices after the nodes are added.
  • Do not set the CheckBoxes property to true! All three CheckBoxes are virtual and you access them after casting the nodes to TreeNode3 as its Check1..Check3 properties!
  • I have not implemented 3-State CheckBoxes. You could change the bools to be nullable and then add the code needed in the click and draw events.
  • I have left a few Console.WriteLines in the code for better testing..

更新我添加了一个间距填充属性和几个构造函数。
现在设置的例子形式的代码看起来非常正常:

Update I have added a Spacing and Padding property and a few constructors. Now the form code that sets up the example looks pretty normal:

ucTreeView1.Nodes.Add(new TreeNode3("Bauhaus", true, true, false));
TreeNode3 aNode = ucTreeView1.AddNode("Beatles", true, true, false);
ucTreeView1.Nodes.Add(new TreeNode3("Blur", true, true, false));
ucTreeView1.Nodes.Add(new TreeNode3("Byrds", true, true, false));
ucTreeView1.Nodes.Add(new TreeNode3("Bee Gees", new TreeNode3[]{
    new TreeNode3("Barry", true, false, false),
    new TreeNode3("Robin"),  
    new TreeNode3("Maurice")} ));

TreeNode3 aNodeA = new TreeNode3("John",   true, true,  false);
TreeNode3 aNodeB = new TreeNode3("Paul",   true, true,  true);
TreeNode3 aNodeC = new TreeNode3("George", true, false, true);
TreeNode3 aNodeD = new TreeNode3("Ringo",  true, false, false);

aNode.Nodes.Add(aNodeA);
aNode.Nodes.Add(aNodeB);
aNode.Nodes.Add(aNodeC);
aNode.Nodes.Add(aNodeD);

这篇关于如何显示在C#一个TreeView多个复选框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆