【发布时间】:2009-12-31 02:07:44
【问题描述】:
我是使用树视图的新手,我希望能够确保树视图只能检查一个子节点,如果有人尝试检查多个子节点,它会停止检查事件并取消选择所有父节点和子节点.我该怎么做呢?到目前为止,这就是我所拥有的,但它表现得很古怪。有什么建议吗?
更新:为了澄清一些事情,这是一个win form treeview,父节点是一个类别,每个类别可以包含多个项目。我只希望用户一次能够从该类别中选择一个类别和一项。
private void tvRecipes_BeforeCheck(object sender, TreeViewCancelEventArgs e)
{
int checkedNodeCount = 0;
if (e.Node.Parent != null && !e.Node.Parent.Checked)
e.Cancel = true;
else
{
foreach (TreeNode node in tvRecipes.Nodes)
{
if (node.Checked)
++checkedNodeCount;
if (checkedNodeCount > 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;
}
}
}
经过一番折腾,我找到了我想要的解决方案。我把它贴在下面了:
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 > 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 > 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 && !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 && 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();
}
}
}
}
【问题讨论】:
-
@Nathan,您好,我看到您接受了我的回答,这实际上是一个较长的“评论”,而不是对您问题的具体回答。我不确定我的“长评论'冒充'作为答案”是否值得接受,所以如果你得到“更好的答案”,请不要犹豫选择它。再一次,我可以(温和地)鼓励您稍微澄清一下您的问题。最好的,
-
@Nathan,有几个问题: 1. 根据设计,最终用户无法选中或取消选中类别节点? 2.如果用户可以检查类别(根)节点:但没有在检查的类别节点中选择项目(子节点):这是错误情况吗? 3.只有检查子节点的行为会自动检查根节点,即您刚刚检查的子节点的父节点? 4.如果我被允许取消选中一个类别节点并且我在其父(类别)节点中选中了一个项目节点,当我取消选中项目时ndoe:类别节点(父节点)也必须取消选中?
-
@Nathan,嗨,一旦我们确切知道类别节点(无父节点、根节点)可以做什么和不可以做什么,这种情况可以很容易地用一两个布尔标志来管理,或者,也许,仅通过使用对当前检查的类别节点(无父,根)和当前检查的项目节点(子节点)的两个引用。最好的,
-
我已经用我在周末想出的答案更新了我的问题。