Reputation: 608
My point is to display number of all child nodes at StatusStripLabel. My point is that I want StatusStripLabel to get updated everytime number of child nodes get's changed - I'll add or delete some of already exists. First, I placed code in Public Form
, but it didn't worked as I expected. After some time I came with idea that actually works: I placed the code inside button method. But after that I realized that I'll need to place it in second place, in case of deleting node. So My question is: is there anything that can make it simplier? If my explanation isn't enough, just tell me, I'll try my best.
Code from Public Form
(Because I want that counter to work from the beggining, not after I'll press the button)
childNodeCounter();
toolStripStatusLabel1.Text = "Number of games in database: " + NodeCounter.ToString();
Method:
public void childNodeCounter()
{
NodeCounter = 0;
foreach (TreeNode RootNode in treeView1.Nodes)
{
foreach (TreeNode ChildNode in RootNode.Nodes)
{
NodeCounter++;
}
}
toolStripStatusLabel1.Text = "Number of games in database: " + NodeCounter.ToString();
}
Code inside button method:
private void button1_Click(object sender, EventArgs e)
{
NodeCounter = 0;
foreach (TreeNode RootNode in treeView1.Nodes)
{
foreach (TreeNode ChildNode in RootNode.Nodes)
{
NodeCounter++;
}
}
toolStripStatusLabel1.Text = "Number of games in database: " + NodeCounter.ToString();
}
Edit: Thanks to mr. Hans Passant I wrote this and it works very well:
public int childNodeCounter(TreeNodeCollection nodes)
{
int count = 0;
foreach (TreeNode RootNode in nodes)
{
foreach (TreeNode ChildNode in RootNode.Nodes)
count++;
}
return count;
Event handler looks like this:
toolStripStatusLabel1.Text = "Number of games in database: " + childNodeCounter(treeView1.Nodes);
Upvotes: 0
Views: 140
Reputation: 9526
If you're adding and removing "game" nodes to the treeView, you must be having methods like void AddGame(string title)
and void RemoveGame(string title)
which add/remove (child) nodes - those whose total number you want to count. If I understood well, you want toolStripStatusLabel1.Text
to be automatically updated each time the number of child nodes changes. In that case you can add field
private int nodesCount;
to your Form class and have something like this:
void AddGame(string title)
{
if(InvokeRequired)
{
Invoke(new MethodInvoker(delegate() { AddGame(title); }));
}
else
{
AddGameNodeToTreeView(title); // add new game node to desired place in TreeView
nodesCount++; // increase node counter
toolStripStatusLabel1.Text = "Number of games in database: " + nodesCount;
}
}
RemoveGame()
would be implemented in the same way (or joined with AddGame()
into a single method with one additional argument - bool add
). Both methods could be extended if you're adding/removing multiple nodes in which case you'll be passing title array and updating nodesCount
accordingly.
The advantage of this approach is that you don't have to count nodes in the tree each time before updating toolStripStatusLabel1.Text
. Also, toolStripStatusLabel1.Text
is updated automatically, not only when user clicks the button.
Drawback is that nodesCount
is somewhat redundant information: total number of nodes of interest is 'hidden' in the treeView
. You have to make sure that nodesCount
is in sync with the actual number of nodes.
Upvotes: 0
Reputation: 941635
The natural way to traverse a tree structure is by using recursion. That's always a bit hard to reason through but there are lots of resources available. Doing it iteratively is a lot uglier, you have to use a Stack<> to allow you to backtrack again out of a nested node. I'll therefore post the recursion solution:
private static int CountNodes(TreeNodeCollection nodes) {
int count = nodes.Count;
foreach (TreeNode node in nodes) count += CountNodes(node.Nodes);
return count;
}
Then your event handler becomes:
private void button1_Click(object sender, EventArgs e) {
toolStripStatusLabel1.Text = "Number of games in database: " +
CountNodes(treeView1.Nodes);
}
Upvotes: 1
Reputation: 5722
Three tiny optimizations
Rather that iterate the tree yourself, just use ChildNode.Nodes.GetNodeCount
Rather than repeat the same logic in different places, have your button Click events simply call the UpdateNodeCount()
method.
The text initializer in the first code fragment is redundant, and can be eliminated: the call to childNodeCounter already does the status label update.
Upvotes: 1