我有一个 TreeNode,我需要允许用户只选择一个子节点作为父节点。例子:
-Car
---Ferrari
---Lamborghini
---Porsche
-Shoes
---Nike
---Puma
---Adidas
我可以选择“法拉利”和“耐克”,但不能选择“汽车”或“鞋子”中的其他孩子。我怎样才能做到?
在我这样做之后,我需要像这样连接父母和孩子的文本:汽车:法拉利。
你能帮助我吗?
问候。
如果您需要每棵树选择一个,我建议使用两个 TreeView。我还会质疑您是否需要使用 TreeViews 或者两个 ListBoxes 或 ComboBoxes 是否更合适。
如果你不知道你会有多少“树”,但你知道它们有多深,你可以使用两个或更多的 ListBoxes(或 ListViews)来显示一个列表列表:
Categories:
Shoes: Nike
Cars: Ferrari
Fruits: Apple (selected)
Selected Category (Fruits):
Apple (selected)
Orange
Pear
Kiwi
您可以处理该BeforeCheck
事件并清除兄弟复选框,例如:
private bool skipEvents = false; // this flag to avoid infinite recursion
void treeView1_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
// if is a root (car or shoes), or it's a recursive call, just return
if (skipEvents || e.Node.Parent == null)
return;
skipEvents = true;
foreach (TreeNode sibling in e.Node.Parent.Nodes)
{
// set the other siblings to unchecked
if (sibling != e.Node)
sibling.Checked = false;
}
skipEvents = false;
}
这是一个连接所选父母和孩子的示例:
public string GetSelectionString()
{
string categorySep = Environment.NewLine;
string parentChildSep = " : ";
StringBuilder sb = new StringBuilder();
foreach (TreeNode root in this.treeView1.Nodes)
{
foreach (TreeNode node in root.Nodes)
{
if (node.Checked)
{
if (sb.Length > 0)
sb.Append(categorySep);
sb.Append(root.Text);
sb.Append(parentChildSep);
sb.Append(node.Text);
break;
}
}
}
return sb.ToString();
}
例如,如果选择了 Ferrari 和 Puma,它会返回如下字符串:
Car : Ferrari
Shoes : Puma
根据评论编辑:
此代码执行您在评论中提出的要求(选择/取消选择父母子女):
private bool skipEvents = false; // this flag to avoid infinite recursion
void treeView1_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
// if it's a recursive call, just return
if (skipEvents)
return;
skipEvents = true;
// it's a root (e.g. car or shoes)
if (e.Node.Parent == null)
{
// if root node is going to be checked, just cancel the action (i.e. block parent selection)
if (!e.Node.Checked)
{
e.Cancel = true;
}
}
else
{
foreach (TreeNode sibling in e.Node.Parent.Nodes)
{
// set the other siblings to unchecked
if (sibling != e.Node)
sibling.Checked = false;
}
}
skipEvents = false;
}
void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
// if it's a recursive call, just return
if (skipEvents)
return;
this.skipEvents = true;
// it's a root (e.g. car or shoes)
if (e.Node.Parent == null)
{
// root node has been unchecked, so uncheck the children
if (!e.Node.Checked)
{
foreach (TreeNode child in e.Node.Nodes)
child.Checked = false;
}
}
else
{
// if a child node has been checked --> check the parent
// otherwise, uncheck the parent
e.Node.Parent.Checked = e.Node.Checked;
}
this.skipEvents = false;
}
NB
TreeView
类有一个在 Vista/Windows7 中出现的关于复选框的已知错误。
基本上,如果您双击一个复选框,它不会启动任何事件,因此这种管理将受到影响。要解决此问题,您可以使用本文中解释的类而不是TreeView
.