Sprawdź liczbę sprawdzonych węzłów w TreeView

Jestem nowy w używaniu widoków drzewa i chcę mieć pewność, że widok drzewa może mieć tylko jeden węzeł podrzędny sprawdzony i jeśli ktoś spróbuje sprawdzić więcej niż jeden, zatrzymuje zdarzenie sprawdzające i odznacza wszystkie węzły nadrzędne i podrzędne. Jak bym to zrobił? Do tej pory to jest to, co mam, ale działa dziwacznie. Jakieś sugestie?

Aktualizacja: Aby wyjaśnić niektóre rzeczy, jest to widok drzewa wygranej, a węzeł macierzysty jest kategorią, a każda kategoria może zawierać wiele elementów. Chcę tylko, aby użytkownik mógł wybrać jedną kategorię i jeden element z danej kategorii na raz.

private void tvRecipes_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
    int checkedNodeCount = 0;

    if (e.Node.Parent != null && !e.Node.Parent.Checked)
        e.Cancel = true;
    else
    {
        foreach (TreeNode node in tvRecipes.Nodes)
        {
            if (node.Checked)
                ++checkedNodeCount;

            if (checkedNodeCount > 2)
            {
                MessageBox.Show("Only one recipe can be selected at a time, please deselect the current recipe and try again.", "Too Many Recipes Selected", MessageBoxButtons.OK, MessageBoxIcon.Error);

                e.Cancel = true;
            }
        }
    }

Po jakimś zamieszaniu wymyśliłem rozwiązanie, po którym byłem. Opublikowałem to poniżej:

private bool CheckNumOfSelectedChildern(TreeViewEventArgs e)
{
    bool Valid = true;
    int selectedChildern = 0;

    foreach (TreeNode node in tvRecipes.Nodes)
    {
        if (node.Checked)
        {
            foreach (TreeNode child in node.Nodes)
            {
                if (child.Checked)
                    ++selectedChildern;
            }
        }
    }

    if (selectedChildern > 1)
    {
        MessageBox.Show("Only one recipe per category can be selected at a time, please deselect the current recipe and try again.", "Too Many Recipes Selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
        e.Node.Checked = false;
        e.Node.Parent.Checked = false;
        Valid = false;
    }       
    return Valid;
}

private bool CheckNumOfSelectedParents(TreeViewEventArgs e)
{
    bool Valid = true;
    int selectedParent = 0;

    foreach (TreeNode root in tvRecipes.Nodes)
    {
        if (root.Checked)
            ++selectedParent;
    }

    if (selectedParent > 1)
    {
        MessageBox.Show("Only one recipe category can be selected at a time, please deselect the current recipe and try again.", "Too Many Recipes Selected", MessageBoxButtons.OK, MessageBoxIcon.Error);
        e.Node.Checked = false;
        Valid = false;
    }
    return Valid;
}

private void tvRecipes_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
    if (e.Node.Parent != null && !e.Node.Parent.Checked)
        e.Cancel = true;
    else if (e.Node.Checked)
    {
        foreach (TreeNode child in e.Node.Nodes)
        {
            if (child.Checked)
                e.Cancel = true;
        }
    }
}

private void tvRecipes_AfterCheck(object sender, TreeViewEventArgs e)
{
    if (CheckNumOfSelectedParents(e))
    {
        if (e.Node.Parent != null && e.Node.Parent.Checked)
        {
            if (e.Node.Checked)
            {
                if (CheckNumOfSelectedChildern(e))
                {
                    RecipeDs = RetrieveRecipe.FillRecipeDs(e.Node.Text);
                    DataBindControls();
                }                    
            }
            else
            {
                RemoveLabelsFromLayout();
                RemoveDataBindings();
                RecipeDs.Clear();
                this.Refresh();
            }
        }
    }
}

questionAnswers(4)

yourAnswerToTheQuestion