我有一个使用CheckBoxes属性的Windows应用程序的树视图控件。
有时(通常)在选中或取消选中Tree Node时,我会在下面的静态方法中获得Stack Overflow Exceptions。
有人能指出原因吗?也许甚至告诉我如何以正确的方式做到这一点?
在After Check Event中,我写了以下内容:
void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) {
if (0 < e.Node.Nodes.Count) {
if (e.Node.Checked) {
e.Node.Expand();
TreeNodes_SetChecksTo(e.Node, true);
} else {
if (!TreeNode_SomethingChecked(e.Node)) {
e.Node.Collapse(false);
}
}
}
}
通常,当静态方法中的某些内容触发上面的After Check事件并进入下面的一个静态方法时,抛出异常:
static void TreeNodes_SetChecksTo(TreeNode node, bool value) {
if (node != null) {
if (node.Checked != value) node.Checked = value;
if (0 < node.Nodes.Count) {
foreach (TreeNode sub in node.Nodes) {
TreeNodes_SetChecksTo(sub, value);
}
}
}
}
static bool TreeNode_SomethingChecked(TreeNode node) {
if (node != null) {
if (node.Checked) return true;
if (0 < node.Nodes.Count) {
foreach (TreeNode sub in node.Nodes) {
if (TreeNode_SomethingChecked(sub)) {
return true;
}
}
}
}
return false;
}
答案 0 :(得分:2)
在IsChecked
内设置TreeNodes_SetChecksTo
会导致AfterCheck
事件被提升,从而调用TreeNode_AfterCheck
方法。我怀疑你想在处理事件时禁用/忽略该事件:
private bool latch;
void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) {
if (latch)
return;
latch = true;
try
{
if (0 < e.Node.Nodes.Count) {
if (e.Node.Checked) {
e.Node.Expand();
TreeNodes_SetChecksTo(e.Node, true);
} else {
if (!TreeNode_SomethingChecked(e.Node)) {
e.Node.Collapse(false);
}
}
}
}
finally
{
latch = false;
}
}
答案 1 :(得分:2)
if (node.Checked != value) node.Checked = value;
这是可能导致它的陈述。它会触发AfterCheck事件。当事件处理程序已经运行时,它将再次被调用。你需要保护自己免受攻击,并打破私人领域的递归。像这样:
private bool updatingChecks;
void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) {
if (updatingChecks) return;
updatingChecks = true;
try {
// etc..
}
finally {
updatingChecks = false;
}
}
答案 2 :(得分:0)
每次(子)节点被检查或取消选中时,树都会递归迭代,这种情况经常发生,因为您对AfterCheck回调的每个检查状态更改做出反应。要么“禁止”回调,而它的“实例”已在处理,要么在没有显式递归的情况下执行回调,并让回调隐式执行递归。