这是我想要实现的功能:
通过单击鼠标检查树节点,用户可以多次选择。
当用户按住Ctrl +鼠标时,我想要检查鼠标点击的树节点,并且取消选中所有其他节点。
我有一个版本但不优雅:
有什么建议吗?
如果要测试代码,请将TreeViewAdv和TreeNodeAdv替换为普通的TreeView和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;
}
}
}
}
答案 0 :(得分:2)
使用继承和递归使其更加优雅:
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;
}