I have a TreeView with check boxes, and when a user checks a child 开发者_如何学JAVAnode, I want to go up the tree and check each parent. However, for some reason my application blows up whenever I touch the parent node. For the nodes in my tree, I've extended TreeNode to create my own objects with some data that I need to store in them, but I still reference them as TreeNodes when checking/unchecking. My code looks like this:
//checkBox checked event handler
if (node.Parent != null)
{
checkAllParents(node.Parent);
}
//
private void checkAllParents(TreeNode node)
{
node.Checked = true;
if (node.Parent != null)
{
checkAllParents(node.Parent);
}
}
Ok, figured it out. It wasn't a circular reference but it was most certainly circular in nature. This was a big dumb mistake on my part..in the event handler I was using recursion to check DOWN the tree as well...I implemented this a while ago and didn't really think about it, so when I added another piece of recursion to check up the tree I ended up with an infinite loop between the recursion function and the event handler (which was getting called every time the recursive function checked one of the nodes..the After_checked event). Bah.
If you really have a circular reference then you would get a stack overflow, which cannot be caught. Try to modify your code to get rid of the recursion:
// checkBox checked event handler
checkAllParents(node);
private void checkAllParents(TreeNode node)
{
var parent = node.Parent;
while (parent != null) {
{
parent.Checked = true;
parent = parent.Parent;
}
}
If app enters an infinite loop then you do have a circular reference. You could further modify the code to catch circular references:
private void checkAllParents(TreeNode node)
{
var parent = node.Parent;
var visitedNodes = new List<TreeNode>();
while (parent != null)
{
if (visitedNodes.Contains(parent))
throw new InvalidOperationException("Circular reference!");
visitedNodes.Add(parent);
parent.Checked = true;
parent = parent.Parent;
}
}
Of course this is not the right place to handle circular references. But if it helps..
It must be a infinite recursion that is blowing the stack (a stack overflow no less). node.Parent must never be evaluating to null. It won't be caught in a try catch because your code isn't throwing an exception, you are just causing a stack overflow and it is the .net frameworkthat throw the exception. You will also be triggering the recursion multiple times, every time you set node.Checked = true; you will fire of the event handler again but you also call check all parents again, i would remove the recursive call to check all parents and just set the node to checked, the event handler will do the recursion for you.
精彩评论