使用.NET 4 WinForms 我们假设我们的课程定义为:
public class Item
{
public int ID { get; set; }
public int Key { get; set; }
public int Value { get; set; }
}
和一个清单:
List<Item> items;
包含以下内容:
Key Value
--- -----
1 1
1 2
1 3
4 4
4 5
2 6
2 7
7 8
我从此列表中填充TreeView,以便根树节点是具有相同键和值的节点。我就是这样做的:
var roots = items.Where(x => x.Key == x.Value);
foreach (var root in roots)
{
AddNode(treeView1.Nodes, root, items);
}
AddNode函数是一个如下定义的递归函数:
void AddNode(TreeNodeCollection nodes, Item current, IList<Item> items)
{
TreeNode treenode = nodes.Add(current.Value.ToString(), current.Value.ToString());
var children = items.Where(x => x.Key == current.Value && x.ID != current.ID);
foreach (var child in children)
{
AddNode(treenode.Nodes, child, items);
}
}
这将产生以下TreeView结构:
_1
|_2
| |_6
| |_7
| |_8
|
|_3
_4
|_5
但是,我想要的是创建一个结构,该结构仅包含至少有一个子节点的根节点,该子节点至少有一个子节点拥有它。在这种情况下,具有值&#34; 1&#34;的根项目有一个有价值的孩子&#34; 2&#34;这又有至少一个孩子。根值&#34; 4&#34;有一个有价值的孩子&#34; 5&#34;但那个孩子没有孩子所以我想省略它。生成的TreeView将如下所示:
_1
|_2
| |_6
| |_7
| |_8
|
|_3
为了进一步澄清,这是我用来清理TreeView后填充的代码:
List<TreeNode> ToRemove = new List<TreeNode>();
foreach (TreeNode n in treeView1.Nodes)
{
if (n.Nodes.Count == 0)
ToRemove.Add(n);
else if (!n.Nodes.Cast<TreeNode>().Any(x => x.Nodes.Count > 0))
ToRemove.Add(n);
}
ToRemove.ForEach(x => treeView1.Nodes.Remove(x)));
如何在填充TreeView之前执行此类清理?
修改 的
根据Aaron的建议,我修改了这样的代码:
var roots = items.Where(x => x.Key == x.Value);
foreach (var root in roots)
{
Add2ndLevelNode(treeView1.Nodes, root, items);
}
功能&#34; Add2ndLevelNode&#34;看起来像这样:
void Add2ndLevelNode(TreeNodeCollection nodes, Item current, IList<Item> items)
{
var children = items.Where(x => x.Key == current.Value && x.ID != current.ID);
bool doIt = false;
foreach (var child in children)
{
if (items.Any(x => x.Key == child.Value))
doIt = true;
}
if (doIt)
{
TreeNode treenode = nodes.Add(current.Value.ToString(), current.Value.ToString());
foreach (var child in children)
{
AddNode(treenode.Nodes, child, items);
}
}
}
还有其他更优雅的方式吗?这样,它需要对孩子们进行两次for-each循环。
答案 0 :(得分:1)
void AddNode(TreeNodeCollection nodes, Item current, IList<Item> items)
{
TreeNode treenode = nodes.Add(current.Value.ToString(), current.Value.ToString());
var children = items.Where(x => x.Key == current.Value && x.ID != current.ID);
foreach (var child in children)
{
if(items.Where(x => x.Key == child.Value).Count() > 1)
AddNode(treenode.Nodes, child, items);
}
}
答案 1 :(得分:1)
显然,这可以在不绕过第二级节点的子节点两次的情况下完成,以便检查它们中是否有自己的子节点。所以,根据Aaron的建议,我修改了这样的代码:
var roots = items.Where(x => x.Key == x.Value);
foreach (var root in roots)
{
Add2ndLevelNode(treeView1.Nodes, root, items);
}
功能&#34; Add2ndLevelNode&#34;看起来像这样:
void Add2ndLevelNode(TreeNodeCollection nodes, Item current, IList<Item> items)
{
var children = items.Where(x => x.Key == current.Value && x.ID != current.ID);
bool doIt = false;
foreach (var child in children)
{
if (items.Any(x => x.Key == child.Value))
doIt = true;
}
if (doIt)
{
TreeNode treenode = nodes.Add(current.Value.ToString(), current.Value.ToString());
foreach (var child in children)
{
AddNode(treenode.Nodes, child, items);
}
}
}