seleccionado obtener nodo net leer ejemplos control borrar atributos c# winforms xml-parsing treeview

obtener - treeview c# ejemplos



Ocultar nodo en la lista de vista de árbol. Cª# (1)

No está claro por su pregunta si el filtro es estático o si puede ser configurado por el usuario. Suponiendo que el filtro se puede configurar dinámicamente, lo que podría hacer es (re) cargar el árbol desde el XML siempre que el filtro cambie, reciclando nodos existentes, creando nuevos nodos según sea necesario y eliminando nodos filtrados. (Por supuesto, esto también funciona si el filtro es estático).

Primero, extraiga un método auxiliar para volver a llenar un árbol desde XML, reciclando los nodos por nombre cuando sea apropiado:

public delegate string GetString<T>(T input); // No Func<T, TResult> in c# 2.0 public static class XmlTreeViewHelper { public static void AddOrMergeNodes(TreeNodeCollection treeNodeCollection, XmlNodeList xmlNodeList, GetString<XmlNode> getNodeName, GetString<XmlNode> getNodeText, Predicate<XmlNode> filter) { Dictionary<string, List<TreeNode>> dict = ToNodeDictionary(treeNodeCollection); int index = 0; foreach (XmlNode inXmlNode in xmlNodeList) { AddOrMergeNode(treeNodeCollection, inXmlNode, ref index, getNodeName, getNodeText, filter, dict); } foreach (List<TreeNode> list in dict.Values) foreach (TreeNode leftover in list) { treeNodeCollection.Remove(leftover); } } static bool IsNodeAtIndex(TreeNodeCollection nodes, TreeNode node, int index) { // Avoid n-squared nodes.IndexOf(node). if (index < 0 || index >= nodes.Count) return false; return nodes[index] == node; } static void AddOrMergeNode(TreeNodeCollection treeNodeCollection, XmlNode inXmlNode, ref int index, GetString<XmlNode> getNodeName, GetString<XmlNode> getNodeText, Predicate<XmlNode> filter, Dictionary<string, List<TreeNode>> dict) { if (filter != null && !filter(inXmlNode)) return; string treeName = getNodeName(inXmlNode); string treeText = (getNodeText == null ? treeName : getNodeText(inXmlNode)); bool added = false; TreeNode treeNode; if (!DictionaryExtensions.TryRemoveFirst(dict, treeName, out treeNode)) { treeNode = new TreeNode(); treeNode.Name = treeName; treeNode.Text = treeText; added = true; treeNodeCollection.Insert(index, treeNode); } else { if (!IsNodeAtIndex(treeNodeCollection, treeNode, index)) { treeNodeCollection.Remove(treeNode); treeNodeCollection.Insert(index, treeNode); } } index++; if (treeNode.Text != treeText) treeNode.Text = treeText; if (inXmlNode.HasChildNodes) AddOrMergeNodes(treeNode.Nodes, inXmlNode.ChildNodes, getNodeName, getNodeText, filter); else treeNode.Nodes.Clear(); if (added) treeNode.ExpandAll(); } /// <summary> /// Returns a dictionary of tree nodes by node name. /// </summary> /// <param name="nodes"></param> /// <returns></returns> static Dictionary<string, List<TreeNode>> ToNodeDictionary(TreeNodeCollection nodes) { Dictionary<string, List<TreeNode>> dict = new Dictionary<string, List<TreeNode>>(); foreach (TreeNode node in nodes) DictionaryExtensions.Add(dict, node.Name, node); return dict; } } public static class DictionaryExtensions { public static void Add<TKey, TValueList, TValue>(IDictionary<TKey, TValueList> listDictionary, TKey key, TValue value) where TValueList : IList<TValue>, new() { if (listDictionary == null) throw new ArgumentNullException(); TValueList values; if (!listDictionary.TryGetValue(key, out values)) listDictionary[key] = values = new TValueList(); values.Add(value); } public static bool TryGetValue<TKey, TValueList, TValue>(IDictionary<TKey, TValueList> listDictionary, TKey key, int index, out TValue value) where TValueList : IList<TValue> { TValueList list; if (!listDictionary.TryGetValue(key, out list)) return Returns.False(out value); if (index < 0 || index >= list.Count) return Returns.False(out value); value = list[index]; return true; } public static bool TryRemoveFirst<TKey, TValueList, TValue>(IDictionary<TKey, TValueList> listDictionary, TKey key, out TValue value) where TValueList : IList<TValue> { TValueList list; if (!listDictionary.TryGetValue(key, out list)) return Returns.False(out value); int count = list.Count; if (count > 0) { value = list[0]; list.RemoveAt(0); if (--count == 0) listDictionary.Remove(key); return true; } else { listDictionary.Remove(key); // Error? return Returns.False(out value); } } } public static class Returns { public static bool False<TValue>(out TValue value) { value = default(TValue); return false; } }

A continuación, cargue (vuelva a cargar) dinámicamente el XML y aplique el filtro que sea apropiado:

private void ReloadTreeFromXmlDocument(XmlDocument dom) { treeView1.BeginUpdate(); try { XmlTreeViewHelper.AddOrMergeNodes(treeView1.Nodes, dom.DocumentElement.ChildNodes, GetTreeNodeName, GetTreeNodeText, FilterNode); } finally { treeView1.EndUpdate(); } } static string GetTreeNodeName(XmlNode inXmlNode) { string text = GetAttributeText(inXmlNode, "name"); if (string.IsNullOrEmpty(text)) text = inXmlNode.Name; return text; } static string GetTreeNodeText(XmlNode inXmlNode) { string text = GetAttributeText(inXmlNode, "name"); if (string.IsNullOrEmpty(text)) { if (inXmlNode.HasChildNodes) { text = inXmlNode.Name; } else { text = (inXmlNode.OuterXml).Trim(); } } return text; } string filter = "_start"; // Reload when this changes bool FilterNode(XmlNode inXmlNode) { return FilterNode(inXmlNode, filter /*filterComboBox.Text*/); } bool FilterNode(XmlNode inXmlNode, string nodeNameFilter) { if (inXmlNode.Name == "namespace" && inXmlNode.ChildNodes.Count == 0 && string.IsNullOrEmpty(GetAttributeText(inXmlNode, "name"))) return false; if (!string.IsNullOrEmpty(nodeNameFilter)) { string text = GetTreeNodeText(inXmlNode); if (text.Contains(nodeNameFilter)) return false; } return true; } static string GetAttributeText(XmlNode inXmlNode, string name) { XmlAttribute attr = (inXmlNode.Attributes == null ? null : inXmlNode.Attributes[name]); return attr == null ? null : attr.Value; }

Después de respaldar mi solución para .Net 2.0, esto es lo que obtengo:

Estoy usando VS 2005 C #, trabajando en un WinForm sin terminar.

He analizado un XML en una lista de vista en árbol, pero tengo algunos problemas. Quiero saber si hay una manera de ocultar / filtrar / eliminar un determinado nodo que contenga un "_this_text" en su nombre sin tener que depender de un cuadro de texto.

Esto es lo que tengo para el programa (felicitaciones a quienes me ayudaron a desarrollar esto):

#region "***** XML Parsing *****" private void Form1_Load_1(object sender, EventArgs e) { // Initialize the controls and the form. //label1.Text = "File Path"; textBox2.Text = Application.StartupPath + "//Continental.vsysvar"; //button6.Text = "XML"; //this.Text = "Software Validation"; } private TreeNode selectedNode = null; private void button6_Click(object sender, EventArgs e) { try { // SECTION 1. Create a DOM Document and load the XML data into it. XmlDocument dom = new XmlDocument(); dom.Load(textBox2.Text); // SECTION 2. Initialize the TreeView control. treeView1.Nodes.Clear(); /*treeView1.Nodes.Add(new TreeNode(dom.DocumentElement.Name)); TreeNode tNode = new TreeNode(); tNode = treeView1.Nodes[0];*/ foreach (XmlNode node in dom.DocumentElement.ChildNodes) { if (node.Name == "namespace" && node.ChildNodes.Count == 0 && string.IsNullOrEmpty(GetAttributeText(node, "name"))) continue; AddNode(treeView1.Nodes, node); } treeView1.ExpandAll(); } /* catch (XmlException xmlEx) { MessageBox.Show(xmlEx.Message); }*/ catch (Exception ex) { MessageBox.Show(ex.Message); } } private void LoadTreeFromXmlDocument(XmlDocument dom) { try { // SECTION 2. Initialize the TreeView control. treeView1.Nodes.Clear(); // SECTION 3. Populate the TreeView with the DOM nodes. foreach (XmlNode node in dom.DocumentElement.ChildNodes) { if (node.Name == "namespace" && node.ChildNodes.Count == 0 && string.IsNullOrEmpty(GetAttributeText(node, "name"))) continue; AddNode(treeView1.Nodes, node); } treeView1.ExpandAll(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } static string GetAttributeText(XmlNode inXmlNode, string name) { XmlAttribute attr = (inXmlNode.Attributes == null ? null : inXmlNode.Attributes[name]); return attr == null ? null : attr.Value; } private void AddNode(TreeNodeCollection nodes, XmlNode inXmlNode) { if (inXmlNode.HasChildNodes) { string text = GetAttributeText(inXmlNode, "name"); if (string.IsNullOrEmpty(text)) text = inXmlNode.Name; TreeNode newNode = nodes.Add(text); XmlNodeList nodeList = inXmlNode.ChildNodes; for (int i = 0; i <= nodeList.Count - 1; i++) { XmlNode xNode = inXmlNode.ChildNodes[i]; AddNode(newNode.Nodes, xNode); } } else { // If the node has an attribute "name", use that. Otherwise display the entire text of the node. string text = GetAttributeText(inXmlNode, "name"); if (string.IsNullOrEmpty(text)) text = (inXmlNode.OuterXml).Trim(); TreeNode newNode = nodes.Add(text); } } #endregion

Y aquí hay un extracto del archivo XMl, ya que es bastante largo:

<?xml version="1.0" encoding="utf-8"?> <systemvariables version="4"> <namespace name="" comment=""> <namespace name="_01_Test_Preparation" comment=""> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_02_Shipping_Status_Check" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_02_Shipping_Status_Check_start" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_01_Get_Dem_ID" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_01_Get_Dem_ID_start" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_04_ECU_Version_Check_start" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_03_Test_Run_Init" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_04_ECU_Version_Check" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_05_DEM_Reader" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_03_Test_Run_Init_start" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> <variable anlyzLocal="2" readOnly="false" valueSequence="false" unit="" name="_01_05_DEM_Reader_start" comment="" bitcount="32" isSigned="true" encoding="65001" type="int" startValue="0" minValue="0" minValuePhys="0" maxValue="4" maxValuePhys="4" /> </namespace>

Lo que realmente quiero lograr es ocultar o filtrar los nodos que contienen este texto "_start" encontrado en su nombre. Por lo tanto, todos los nodos que contengan "_this_start" en su nombre quedarán ocultos para el usuario. He leído que técnicamente no es posible habilitar o deshabilitar la visibilidad, sino que se agota el texto y otras cosas.

Gracias de antemano.