Data synchronization between XML document and Treeview control operation in C#

  In the previous article " C# uses XML and Treeview to implement complex data collection functions ", Treeview was used to display XML data. The question is how to change the content of XML data synchronously if operations are performed on Treeview?

 

  This problem seems simple, but it is a little troublesome to implement.

  Operational functions to be implemented:

  ⑴ If you click Radio, that is, the radio icon, you need to find the node in the XML document, clear the selection attributes of all nodes at the same level, and then set the selection attribute of the node to "true".

  ⑵ If you click the Checkbox, that is, the multi-select icon, you need to find the node in the XML document, and then set the selection attribute of the node to "true".

  ⑶ If you click the textbook, that is, the text input icon, you need to find the node in the XML document, and then rewrite the value attribute of the node.

  ⑷ Click the label, only the icon replacement action will be performed, and the XML content will not be changed.

  ⑸As long as you click Radio, Checkbox, and Textbook, automatic calculation is required. Automatic calculation rules: If there is no calculation formula attribute, then the parent node is equal to the sum of the values ​​of the child nodes. If there is a calculation formula, the result needs to be obtained according to the calculation formula.

  The code implementation to solve ⑴, ⑵ and ⑶ is recorded here.

  The specific implementation code in the treeView1_MouseDown(object sender, MouseEventArgs e) event:

//在XML内容中进行操作,找到该子项目并修改子项目的属性值,就是修改XML文档的内容
//找到该节点
TreeNode SelectedNode =treeView1.GetNodeAt(e.X, e.Y);
//得到全路径名
string StrCurrentPath= SelectedNode.FullPath;
//找第一个"\"
int FirstIndex = StrCurrentPath.IndexOf("\\");
//找最后一个"\"
int LastIndex =StrCurrentPath.LastIndexOf("\\");
//得到在XML文档中父节点的全路径名称
string StrParentPath= StrCurrentPath.Substring(FirstIndex+1,LastIndex - FirstIndex -1);
//得到当前节点名称
string StrCurrentNodeName= StrCurrentPath.Substring(LastIndex+1);
//找到节点
XmlNode TargetNode = FindNodeAtXmlContent(XmlDoc.DocumentElement, StrParentPath);
//处理节点信息
HandleNodeInfoAtXmlContent(TargetNode, StrCurrentNodeName);
//保存处理后的XML文档内容
StrXmlContent = XmlDoc.OuterXml;

  The search function finds the node based on the node being searched and the path.

  Generally, recursion is used to search. The loop used here:

  Decompose the path into a string array, such as "\Node 1\Node 2\Node 3\Node 4", and decompose it into "Node 1", "Node 2", "Node 3", "Node 4" , first find "node 1", and then find the following ones in sequence, so fast.

  Implemented code:

        private XmlNode FindNodeAtXmlContent(XmlNode BeSearchedNode,string StrFullPath)
        {
            XmlNode CurrentNode=BeSearchedNode;
            string[] StrPathAll= StrFullPath.Split('\\');
            foreach(string StrPath in StrPathAll)
            {
                bool Finded= false;
                foreach(XmlNode xmlNode in CurrentNode.ChildNodes)
                {
                    if (xmlNode.Name.Trim()==StrPath.Trim())
                    {
                        Finded = true;
                        CurrentNode= xmlNode;//找到对应的节点
                        break;
                    }
                }
                if(!Finded)
                {
                    return null;//没有找到对应的节点
                }
            }
            return CurrentNode;
        }

  Handling function, if the parent node is found, changes the relevant information:

        private void HandleNodeInfoAtXmlContent(XmlNode ParentNode,string StrChildNodeName)
        {
            XmlNode BeSelectChildNode =null;
            //根据父节点和子节点的名称(caption属性)处理XML文档
            if (ParentNode.Attributes["type"] != null)
            {
                string StrNodeType = ParentNode.Attributes["type"].Value;
                if (StrNodeType=="Radio")
                {
                    foreach(XmlNode ChildNode in ParentNode.ChildNodes)
                    {
                        textBox2.Text += "节点caption:" + ChildNode.Attributes["caption"].Value+Environment.NewLine;
                        //单选,先将父节点下的子节点的select属性全部删除
                        if (ChildNode.Attributes["select"] != null)
                        {
                            ChildNode.Attributes.Remove(ChildNode.Attributes["select"]);
                        }
                        //找到子节点
                        if (ChildNode.Attributes["caption"].Value ==StrChildNodeName.Trim())
                        {
                            BeSelectChildNode = ChildNode;
                        }
                    }
                    //添加select属性
                    XmlAttribute SelectedAttr = XmlDoc.CreateAttribute("select");
                    SelectedAttr.Value= "true";
                    BeSelectChildNode.Attributes.Append(SelectedAttr);                    
                }
                if (StrNodeType == "Checkbox")
                {
                    foreach (XmlNode ChildNode in ParentNode.ChildNodes)
                    {
                        //多选,找到并添加select属性
                        //找到子节点
                        if (ChildNode.Attributes["caption"].Value == StrChildNodeName.Trim())
                        {
                            BeSelectChildNode = ChildNode;
                        }
                    }
                    //添加select属性
                    XmlAttribute SelectedAttr = XmlDoc.CreateAttribute("select");
                    SelectedAttr.Value = "true";
                    BeSelectChildNode.Attributes.Append(SelectedAttr);
                }
                if (StrNodeType == "Textbox")
                {
                    foreach (XmlNode ChildNode in ParentNode.ChildNodes)
                    {
                        //文本输入框,找到并更改value属性
                        //找到子节点
                        if (ChildNode.Attributes["caption"].Value == StrChildNodeName.Trim())
                        {
                            BeSelectChildNode = ChildNode;
                        }
                    }
                    //更改value属性属性
                    XmlAttribute SelectedAttr = XmlDoc.CreateAttribute("value");
                    SelectedAttr.Value = StrCurrentTextboxValue;
                    BeSelectChildNode.Attributes.Append(SelectedAttr);
                }
            }
        }

  Through the above code, the operation of Treeview can be synchronously updated and consistent with the content of the actual XML document.

Guess you like

Origin blog.csdn.net/dawn0718/article/details/132106187