title: Check number of checked nodes in TreeView
body: <p>I am new to using tree views and I want to be able to make sure the tree view can only have one child node checked and if someone tries to check more then one it stops the check event and deselects all parent and child nodes.  How would I go about doing this?  So far this is what I've got but it is acting quirky.  Any suggestions?</p>
  
  <p><strong>Update:</strong> To clarify some things this is a win form treeview and the parent node is a category and each category can contain multiple items.  I only want the user to be able to select one category and one item from the category at a time.</p>
  
  <pre><code>private void tvRecipes_BeforeCheck(object sender, TreeViewCancelEventArgs e)
  {
      int checkedNodeCount = 0;
  
      if (e.Node.Parent != null &amp;&amp; !e.Node.Parent.Checked)
          e.Cancel = true;
      else
      {
          foreach (TreeNode node in tvRecipes.Nodes)
          {
              if (node.Checked)
                  ++checkedNodeCount;
  
              if (checkedNodeCount &gt; 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;
              }
          }
      }
  </code></pre>
  
  <p>After some messing around I figured out the solution I was after.  I have posted it below:</p>
  
  <pre><code>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 &gt; 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 &gt; 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 &amp;&amp; !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 &amp;&amp; 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();
              }
          }
      }
  }
  </code></pre>