Reputation: 132
This is the feature i want to implement:
check a tree node by click mouse as normal, user can multiple select.
when user hold Ctrl+ mouse, i want the tree node which mouse clicked to be checked and all other nodes are unchecked.
I have a version but it is not elegant:
Any suggestions?
If you want to test the code, replace TreeViewAdv and TreeNodeAdv with normal TreeView and TreeNode.
using Syncfusion.Windows.Forms.Tools;
namespace treeviewtest
{
public partial class Form1 : Form
{
TreeNodeAdv CurrentNode = null;
public Form1()
{
InitializeComponent();
}
private void treeViewAdv1_AfterCheck(object sender, Syncfusion.Windows.Forms.Tools.TreeNodeAdvEventArgs e)
{
TreeViewAdv tree = sender as TreeViewAdv;
if (Control.ModifierKeys == Keys.Control
&& e.Action!= TreeViewAdvAction.Unknown)
{
foreach (TreeNodeAdv node in tree.Nodes)
{
if (node.CheckState == CheckState.Checked && node != CurrentNode)
node.Checked = false;
foreach (TreeNodeAdv n in node.WalkTree())
{
if (n.CheckState == CheckState.Checked && n != CurrentNode)
n.Checked = false;
}
}
}
CurrentNode = null;
}
private void treeViewAdv1_BeforeCheck(object sender, TreeNodeAdvBeforeCheckEventArgs e)
{
if (Control.ModifierKeys == Keys.Control && CurrentNode == null)
{
CurrentNode = e.Node;
if (e.NewCheckState == CheckState.Unchecked)
{
TreeViewAdv tree = sender as TreeViewAdv;
foreach (TreeNodeAdv node in tree.Nodes)
{
if (node.CheckState == CheckState.Checked && node != CurrentNode)
node.Checked = false;
foreach (TreeNodeAdv n in node.WalkTree())
{
if (n.CheckState == CheckState.Checked && n != CurrentNode)
n.Checked = false;
}
}
e.Cancel = true;
}
}
}
}
public static class externtree
{
public static IEnumerable<TreeNodeAdv> WalkTree(this TreeNodeAdv node)
{
if (node == null)
yield break;
// return itself first
yield return node;
// return children
if (node.HasChildren)
{
foreach (TreeNodeAdv cNode in node.Nodes)
foreach (TreeNodeAdv iNode in cNode.WalkTree())
yield return iNode;
}
}
}
}
Upvotes: 1
Views: 2731
Reputation: 942267
Make it elegant with inheritance and recursion:
using System;
using System.Windows.Forms;
class MyTreeView : TreeView {
protected override void OnAfterCheck(TreeViewEventArgs e) {
if (checking) return;
checking = true;
if (e.Node.Checked && (Control.ModifierKeys & Keys.Control) == Keys.Control) {
uncheckNodes(this.Nodes, e.Node);
}
checking = false;
base.OnAfterCheck(e);
}
private void uncheckNodes(TreeNodeCollection nodes, TreeNode except) {
foreach (TreeNode node in nodes) {
if (node != except) node.Checked = false;
uncheckNodes(node.Nodes, except);
}
}
private bool checking;
}
Upvotes: 2