0

TreeNode があり、ユーザーが親に対して子ノードを 1 つだけ選択できるようにする必要があります。例:

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

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

「フェラーリ」と「ナイキ」は選択できますが、「車」と「靴」の他の子は選択できません。どうすれば作れますか?
これを行った後、次のように親と子のテキストを連結する必要があります: Car: Ferrari.
手伝って頂けますか?
よろしく。

4

2 に答える 2

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 に答える
0

ツリーごとに 1 つの選択が必要な場合は、2 つの TreeView を使用することをお勧めします。また、TreeView を使用する必要があるかどうか、または 2 つの ListBox または ComboBox の方が適切かどうかについても質問します。

「ツリー」の数がわからないが、その深さはわかっている場合は、2 つ以上の ListBox (または ListView) を使用して、基本的にリストのリストを表示できます。

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

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