項目用到了TreeView控件,父節點子節點勾選需要關聯。子節點勾選,父節點同步。父節點勾選,所有子節點都勾選,並遞歸。網上找了一圈,好多代碼都不滿足要求。節點勾選,向下遞歸子節點,都實現了。節點勾選,向上遞歸,父節點同步勾選,也實現了。但是節點去除勾選,應該判斷其同級所有節點,若同級節點都處於未勾選狀態,則應該去除父節點勾選狀態,並向上遞歸。這一點,沒有找到合適的代碼。就自己寫了這部分代碼。僅僅只是實現這個效果,代碼還有優化的空間,後續有時間再來修改了。
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
//僅執行由鼠標勾選觸發的事件,避免代碼遞歸執行勾選,無限循環
if (e.Action != TreeViewAction.ByMouse)
return;
this.UpdateNodesCheckState(e.Node);
}
/// <summary>
/// 設置節點上下級狀態
/// </summary>
/// <param name="node"></param>
private void UpdateNodesCheckState(TreeNode node)
{
//設置子節點,向下遞歸
SetChildNode(node);
//設置父節點,向上遞歸
if (node.Checked)
{
//勾選
SetParentNodeChecked(node);
}
else
{
//未勾選
//若同級節點都未勾選,則父節點去除勾選。不斷向上遞歸判斷
SetParentNodeUnChecked(node);
}
}
/// <summary>
/// 節點勾選,設置父節點選中。並向上遞歸設置選中
/// </summary>
/// <param name="node"></param>
private void SetParentNodeChecked(TreeNode node)
{
if (node.Parent != null)
{
node.Parent.Checked = true;
SetParentNodeChecked(node.Parent);
}
}
/// <summary>
/// 節點未勾選,設置上級節點狀態
/// 判斷同級節點狀態,設置父節點
/// </summary>
/// <param name="node"></param>
private void SetParentNodeUnChecked(TreeNode node)
{
bool IaAllUnChecked = true;
if (node.Parent != null)
{
for (int i = 0; i < node.Parent.Nodes.Count; i++)
{
if (node.Parent.Nodes[i].Checked)
{
IaAllUnChecked = false;
break;
}
}
}
//當前節點的所有同級節點均未勾選,則父節點設置狀態未勾選。向上遞歸
if (IaAllUnChecked && node.Parent != null)
{
node.Parent.Checked = node.Checked;
SetParentNodeUnChecked(node.Parent);
}
}
/// <summary>
/// 父節點變化,其子節點同步變化,其所有子節點與父節點勾選狀態保持一致。
/// </summary>
/// <param name="node"></param>
private void SetChildNode(TreeNode node)
{
foreach (TreeNode childNode in node.Nodes)
{
childNode.Checked = node.Checked;
if (node.Nodes.Count > 0)
SetChildNode(childNode);
}
}