我正在尝试从XmlDocument填充树视图。 树的根被设置为“脚本”,并且从根开始,下一级应该是XML部门内的“部门”。我可以从XML文档中获取数据没问题。我的问题是当循环遍历XmlDocument并将节点添加到根节点时,我想确保如果某个部门已经在树视图中,那么它不会再次添加。我还应该补充一点,每个部门还有一个需要成为部门子节点的脚本列表。
到目前为止我的代码是:
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(scriptInformation);
TreeNode t1;
TreeNode rootNode = new TreeNode("Script View");
treeView1.Nodes.Add(rootNode);
foreach (XmlNode node in xDoc.SelectNodes("//row"))
{
t1 = new TreeNode(node["DEPARTMENT"].InnerXml);
//How to check if node already exists in treeview?
}
感谢。
答案 0 :(得分:3)
if(treeView1.Nodes.ContainsKey("DEPARTMENT")){
//...
}
编辑:递归方法:
bool exists = false;
foreach (TreeNode node in treeView1.Nodes) {
if (NodeExists(node, "DEPARTMENT"))
exists = true;
}
private bool NodeExists(TreeNode node, string key) {
foreach (TreeNode subNode in node.Nodes) {
if (subNode.Text == key) {
return true;
}
if (node.Nodes.Count > 0) {
NodeExists(node, key);
}
}
return false;
}
答案 1 :(得分:1)
根据XML文件的大小,您可以考虑使用关联的List
进行快速查找。当您将每个节点添加到TreeView
时,也会将其添加到List
。
答案 2 :(得分:1)
您可以这样做:
TreeNode parentNode = t1.Parent;
if (parentNode != null}
{
if(parentNode.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
{
//Add node
}
}
else
{
bool isFound = true;
if (treeView1.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
{
isFound = false;
}
if(!isFound)
{
//Add node
}
}
答案 3 :(得分:1)
如果您的XML文档具有一个集合结构,其中“部门”将始终编入索引为1;
即:
index:[0] Scripts
index:[1] Department
index:[2] Script
index:[1] Department2
index:[2] Script
然后,您可以将以下代码封装到一个方法中,其中'name'是一个字符串参数,返回类型是boolean。
foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
if (node.Name.ToLower() == name.ToLower()) {
return true;
}
}
return false;
我们的想法是,在创建TreeNode之前,每次在Xml中遇到“Department”节点时都会调用该函数。
完整示例:
private bool DepartmentNodeExists(string name) {
foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
if (node.Name.ToLower() == name.ToLower()) {
return true;
}
}
return false;
}
最后,简单方式:
private bool DepartmentNodeExists(string name) {
if (uxTreeView.Nodes[0].ContainsKey(name)) {
return true;
}
else {
return false;
}
}
这些都只是重构并封装到他们自己的命名方法中,你当然可以调用:
if (uxTreeView.Nodes[0].ContainsKey(name)) {
// do not create TreeNode
}
...在解析XML时。 PS。这些示例都假设您已经创建了TreeView中的第一个根节点并将其添加到TreeView中。
答案 4 :(得分:1)
http://www.vbdotnetforums.com/listviews-treeviews/13278-treeview-search.html#post39625
http://forums.asp.net/t/1645725.aspx/1?Check+if+child+Node+exists+on+treeview
答案 5 :(得分:1)
不确定文件结构......
难道你不能使用Linq到Xml,加载文档并获取不同的行(row = department?)并仅考虑创建TreeNode的那些元素?它比尝试查找是否已添加具有此类文本的节点更有效。
例如:
var rows = ( from row in XDocument.Load(document).Root.Elements("row")
select row
).Distinct(new SampleElementComparerOnNameAttribute());
这里,EqualityComparer是在“name”属性值上创建的,假定doc结构为
<rows><row name='dep1'><script>script1</script><script>script2</script></row><row name='dep1'><script>script3</script><script>script4</script></row></rows>
答案 6 :(得分:1)
我用,
string department = node["DEPARTMENT"].InnerXml;
TreeNode node = parentNode.Nodes[department] ?? parentNode.Nodes.Add(department, department);
该行保证首先查找价值部门,如果没有找到则创建它。您必须在Add()中执行双重输入,以便它具有一个键值,您可以使用.Nodes[department].
答案 7 :(得分:0)
这取决于您输入的结构。由于您未显示添加子节点的确切方式,因此我只能指向Contains
或[{3}}属性的ContainsKey
方法,treeView1
本身,或您添加的任何子节点。您应该使用Add
方法的重载来指定密钥名称以简化查找。