树视图功能可取消选中所有其他节点
本文关键字:其他 节点 视图 功能 可取消 | 更新日期: 2023-09-27 18:36:56
这是我想要实现的功能:
-
正常点击鼠标检查树节点,用户可以多选。
-
当用户按住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;
}
}
}
}
使用继承和递归使其优雅:
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;
}