我在TreeView
(trvP)中添加了一些节点。根元素的Tag
属性设置为Root
。
我试图这样做,如果我检查根元素,所有其他节点将具有相同的状态。但是,执行以下代码会导致StackOverflowException
。
private void trvP_AfterCheck(object sender, TreeViewEventArgs e)
{
if(e.Node.Tag.Equals("Root"))
{
var nodes = TreeViewExtensions.GetAllNodes(e.Node.TreeView);
foreach (TreeNode node in nodes)
node.Checked = e.Node.Checked;
}
}
GetAllNodes
函数的代码:
public static List<TreeNode> GetAllNodes(this TreeView _trv)
{
List<TreeNode> result = new List<TreeNode>();
foreach (TreeNode child in _trv.Nodes)
{
result.AddRange(child.GetAllNodes());
}
return result;
}
public static List<TreeNode> GetAllNodes(this TreeNode _trn)
{
List<TreeNode> result = new List<TreeNode>();
result.Add(_trn);
foreach (TreeNode child in _trn.Nodes)
{
result.AddRange(child.GetAllNodes());
}
return result;
}
从调试开始,它一遍又一遍地运行var nodes = ...
代码,而只在foreach
循环(根节点)内设置单个节点。但是,nodes
是具有正确值的正确节点列表。
我无法理解为什么这种情况反复执行会导致异常。
答案 0 :(得分:1)
GetAllNodes()
的{{1}}扩展名从第一个子节点开始,并为此TreeView
调用GetAllNodes()
扩展名。
此TreeNode
扩展程序会将此GetAllNodes()
添加到结果列表中
因此,列表中的第一个 TreeNode
再次是根节点。
这意味着在行
TreeNode
您设置了根节点的node.Checked = e.Node.Checked;
属性,该属性又为此根节点再次调用处理程序Checked
。这现在无限重复,充斥你的筹码并提升trvP_AfterCheck
。
要解决此问题,请过滤掉根节点:
StackOverflowException
顺便说一下:扩展方法的优点在于你可以在语法上调用它们,就好像它们是instanc方法一样。所以这个
private void trvP_AfterCheck(object sender, TreeViewEventArgs e)
{
if(e.Node.Tag.Equals("Root"))
{
var nodes = e.Node.TreeView.GetAllNodes();
foreach (TreeNode node in nodes)
{
if (node == e.Node) continue; // don't do it for root again
node.Checked = e.Node.Checked;
}
}
}
可以简单地写成
var nodes = TreeViewExtensions.GetAllNodes(e.Node.TreeView)
答案 1 :(得分:0)
你正在递归地调用GetAllNodes,这使得循环进入无限状态..
试
public static List<TreeNode> GetAllNodes(this TreeView _trv)
{
List<TreeNode> result = new List<TreeNode>();
foreach (TreeNode child in _trv.Nodes)
{
result.Add(child);
}
return result;
}
当你已经将treenode循环到_trv.Nodes时,你需要将当前节点添加到foreach语句中。