Reputation: 87
Is there a way to multi-select in a Windows Tree View? Similar to the image below
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
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
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