如何检查树视图(winform)中标签数据与列表项相等的节点
本文关键字:列表 节点 数据 检查 何检查 视图 winform 标签 | 更新日期: 2023-09-27 18:36:18
在下面的代码中,我有一个AccessId列表,它存储在树节点的标签中。如何检查我的列表中标记的节点(或子节点)?
List<AccessFieldSet> AccessList = new List<AccessFieldSet>();
private void GetRolesAccessData(Int32 RolesId)
{
C_RolesUsers Db = new C_RolesUsers();
AccessList = Db.GetRolesAccessData(RolesId);
foreach (AccessFieldSet Afs in AccessList)
{
foreach (TreeNode node in TreeRoles.Nodes)
{
if (node.Tag == Afs.AccessId.ToString())
{
//Check Node is true ?
}
GetTagChildren(node);
}
}
}
private void GetTagChildren(TreeNode Node)
{
TreeNode ChNode = null;
//TreeFieldSet nodeCat = (TreeFieldSet)Node.Tag;
//Int32 nodeCat = (Int32)Node.Tag;
foreach (AccessFieldSet Afs in AccessList)
{
if (Afs.AccessId.ToString() == Node.Tag)
{
//Check Node is true ?
GetTagChildren(ChNode);
}
}
}
我将代码编辑为:
List<AccessFieldSet> AccessList = new List<AccessFieldSet>();
private void GetRolesAccessData(Int32 RolesId)
{
C_RolesUsers Db = new C_RolesUsers();
AccessList = Db.GetRolesAccessData(RolesId);
for (int i = 0; i < TreeRoles.Nodes.Count; i++)
{
CheckedSelectedNodes(i, TreeRoles.Nodes, AccessList);
}
}
private void CheckedSelectedNodes(Int32 i, TreeNodeCollection nodes, List<AccessFieldSet> AccessList)
{
TreeNode node = nodes[i];
for (int j = 0; j < AccessList.Count; j++)
{
foreach (AccessFieldSet Afs in AccessList)
{
if ((int)node.Tag == Afs.AccessId)
{
node.Checked = true;
}
}
}
}
使用新代码,我可以检查节点的标记在 AccessList 中的节点。如何更改子节点(节点的子节点)的代码?
你可以使用递归来非常优雅地做到这一点。
List<AccessFieldSet> accessList = new List<AccessFieldSet>();
private void GetRolesAccessData(Int32 RolesId)
{
C_RolesUsers Db = new C_RolesUsers();
accessList = Db.GetRolesAccessData(RolesId);
foreach (TreeNode node in TreeRoles.Nodes)
{
CheckNodeRecursively(node, accessList);
}
}
private void CheckNodeRecursively(TreeNode node, List<AccessFieldSet> accessList)
{
// Note: You don't need the for loop through 'j'.
foreach (AccessFieldSet afs in accessList)
{
if ((int)node.Tag == afs.AccessId)
{
node.Checked = true;
}
}
foreach (TreeNode childNode in node.Nodes)
{
CheckNodeRecursively(childNode, accessList);
}
}
如果您发现自己经常做这种事情,则可以将递归分解为实用程序方法,并使用 Action 来改变"对每个节点执行操作"逻辑。 例如:
public static void ActOnAllRecursively(this TreeNodeCollection nodes, Action<TreeNode> action)
{
foreach (TreeNode node in nodes)
{
ActOnRecursively(node, action);
}
}
public static void ActOnRecursively(this TreeNode node, Action<TreeNode> action)
{
action(node);
foreach (TreeNode node in node.Nodes)
{
ActOnRecursively(node);
}
}
那么你的代码就像这样:
List<AccessFieldSet> accessList = new List<AccessFieldSet>();
private void GetRolesAccessData(Int32 RolesId)
{
C_RolesUsers Db = new C_RolesUsers();
accessList = Db.GetRolesAccessData(RolesId);
TreeRoles.Nodes.ActOnAllRecursively((node) =>
{
foreach (AccessFieldSet afs in accessList)
{
if ((int)node.Tag == afs.AccessId)
{
node.Checked = true;
}
}
});
}
最后,您可以疯狂地使用 LINQ 并以声明性样式编写特定于应用的代码:
List<AccessFieldSet> accessList = new List<AccessFieldSet>();
private void GetRolesAccessData(Int32 RolesId)
{
C_RolesUsers Db = new C_RolesUsers();
accessList = Db.GetRolesAccessData(RolesId);
TreeRoles.Nodes.ActOnAllRecursively((node) =>
{
node.Checked = accessList.Any(afs => afs.AccessId == (int)node.Tag);
});
}