John Vicious
John Vicious

Reputation: 87

Windows Form Multi-Select for Tree View

Is there a way to multi-select in a Windows Tree View? Similar to the image below

enter image description here

I know that .NET currently doesn't have a multiselect treeview. It is treated as a wrapper around the win32 native treeview control. I would like to avoid the Treeview's Checkbox property if possible. Any suggestions is greatly appreciated!

Upvotes: 0

Views: 2721

Answers (2)

Travis
Travis

Reputation: 56

Im gonna assume you're trying to avoid check boxes. Here is an example:

public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      treeView1.DrawMode = OwnerDrawText;
      treeView1.DrawNode += treeView1_DrawNode;
      treeView1.NodeMouseClick += treeView1_NodeMouseClick;
    }

    private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) {
      // Show checked nodes with an underline
      using (SolidBrush br = new SolidBrush(e.Node.TreeView.BackColor))
        e.Graphics.FillRectangle(br, e.Node.Bounds);
      Font nodeFont = e.Node.NodeFont;
      if (nodeFont == null) nodeFont = e.Node.TreeView.Font;
      if (e.Node.Checked) nodeFont = new Font(nodeFont, FontStyle.Underline);
      using (SolidBrush br = new SolidBrush(e.Node.TreeView.ForeColor))
        e.Graphics.DrawString(e.Node.Text, nodeFont, br, e.Bounds);
      if (e.Node.Checked) nodeFont.Dispose();
    }

    private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
      if (Control.ModifierKeys == Keys.Shift && e.Node.Parent != null) {
        // Extend selection
        bool check = false;
        foreach (TreeNode node in e.Node.Parent.Nodes) {
          if (node.Checked) check = true;
          node.Checked = check;
          if (node == e.Node) break;
        }
      }
      else {
        unselectNodes(treeView1.Nodes);
        e.Node.Checked = true;
      }
    }

Upvotes: 2

foyss
foyss

Reputation: 983

This question has been answered here but I'll briefly answer your question. While it is true that Native Treeview control does not allow multiple selection, you can derive a subclass from it and override its behaviors.

Example code:

checkNodes method:

private void checkNodes(TreeNode node, bool check)
        {
            foreach (TreeNode child in node.Nodes)
            {
                if (child.Checked == true)
                {
                    MessageBox.Show(child.Text);
                } 
                //MessageBox.Show(child.Text);
                checkNodes(child, check);
            }
        }

Treeview method after check:

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action != TreeViewAction.Unknown)
            {
                 if (busy) return;
                busy = true;
                try
                {
                    TreeNode _node = e.Node;

                    checkNodes(e.Node, e.Node.Checked);
                    if (e.Node.Checked)
                    {
                        MessageBox.Show(e.Node.Text);
                    }
                }


                finally
                {
                    busy = false;
                }
            }

        }

It is not trivial to do so, however it can be done.

Upvotes: 2

Related Questions