0

我有一个 TreeNode,我需要允许用户只选择一个子节点作为父节点。例子:

-Car
---Ferrari
---Lamborghini
---Porsche

-Shoes
---Nike
---Puma
---Adidas

我可以选择“法拉利”和“耐克”,但不能选择“汽车”或“鞋子”中的其他孩子。我怎样才能做到?
在我这样做之后,我需要像这样连接父母和孩子的文本:汽车:法拉利。
你能帮助我吗?
问候。

4

2 回答 2

0

如果您需要每棵树选择一个,我建议使用两个 TreeView。我还会质疑您是否需要使用 TreeViews 或者两个 ListBoxes 或 ComboBoxes 是否更合适。

如果你不知道你会有多少“树”,但你知道它们有多深,你可以使用两个或更多的 ListBoxes(或 ListViews)来显示一个列表列表:

Categories:
   Shoes: Nike
   Cars:  Ferrari
   Fruits: Apple (selected)

Selected Category (Fruits):
   Apple (selected)
   Orange
   Pear
   Kiwi
于 2012-12-24T14:13:35.870 回答
0

您可以处理该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.

于 2012-12-24T14:19:37.043 回答