Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Create Editable XML Documents Using XPath and the TreeView Control : Page 5

Adding drag and drop support to your TreeView control needn't be taxing. With XML and Xpath, you can get most of that support for free.


advertisement
Implementing Delete, Rename, and Insert Operations
Most of the hard work's over. You've implemented drag and drop, but for completeness it would be nice to have some basic editing facilities as well. Drawing on the code you've already seen, it only takes four lines to delete a folder:

[C#] string xpath_query = buildXPathQuery(this.SelectedNode); System.Xml.XmlNode node = xml_document.DocumentElement.SelectSingleNode( xpath_query); node.ParentNode.RemoveChild(node); SelectedNode.Remove();


[VB] Dim xpath_query As String = _ buildXPathQuery(Me.SelectedNode) Dim node As System.Xml.XmlNode = _ xml_document.DocumentElement.SelectSingleNode( _ xpath_query) node.ParentNode.RemoveChild(node) SelectedNode.Remove()

Renaming a folder takes a little more thought. While you can call buildXPathQuery to find out which folder to edit, how do you know which attribute, element or sub-element of the returned structure corresponds to that folder's display name? It's a trick question. That's precisely the function of the XPath filter defined earlier. Rather elegantly, you can just apply the transforms one after the other:



[C#] private void XmlTreeView_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e) { string xpath_query = buildXPathQuery(e.Node); System.Xml.XmlNode node = xml_document.DocumentElement.SelectSingleNode( xpath_query); System.Xml.XmlNode label = node.SelectSingleNode(xpath_filter); label.Value = e.Label; }


[VB] Private Sub XmlTreeView_AfterLabelEdit( _ ByVal sender As Object, _ ByVal e As System.Windows.Forms.NodeLabelEditEventArgs) _ Handles MyBase.AfterLabelEdit Dim xpath_query As String = buildXPathQuery(e.Node) Dim node As System.Xml.XmlNode = _ xml_document.DocumentElement.SelectSingleNode( _ xpath_query) Dim label As System.Xml.XmlNode = node.SelectSingleNode(xpath_filter) label.Value = e.Label End Sub

The final challenge lies in working out how to create a new folder on demand. The query filter allows users to navigate the XML document in terms of folders rather than XML elements, which is helpful when you want to move those folders around. But while it can tell you where to insert a folder, it can't tell you anything about what that folder should contain. You could surmise something if all the folders within a document had the same structure and contents, but the goal is to create a method for displaying XML that requires no such prerequisites. Accordingly, I've chosen to delegate the responsibility for this to the application hosting the control. This way, for example, a client could write code such as:

[C#] System.Xml.XmlDocument insert_fragment = new System.Xml.XmlDocument(); insert_fragment.LoadXml( "<product id='New Item'>" + "<description/><ordercode/><price/>" + "<image/></product>"); // The TreeView uses XmlInsertionNode to add // a new folder to the tree's underlying XML // document on request xmlTreeView1.XmlInsertionNode = insert_fragment.DocumentElement;


[VB] Dim insert_fragment As New System.Xml.XmlDocument() insert_fragment.LoadXml(" & _ "<product id='New Item'>" & _ "<description/><ordercode/>"<price/>" & _ "<image/></product>") xmlTreeView1.XmlInsertionNode = _ insert_fragment.DocumentElement

The TreeView control can cache a copy of this structure and use it as a template for building new folders on request. Your only responsibility is to ensure the folder is defined in such a way that the filter query identifies it as a folder. Otherwise, the TreeView control wouldn't display it, and to all intents and purposes, it would look as if it didn't exist. Because the XML generated above is external to the document we're manipulating, it's necessary to import it into the document before using it.

[C#] // First you need to clone the node template, and // import it, because it originates from a different // document System.Xml.XmlNode copy_node = new_node.Clone(); System.Xml.XmlNode insert_node = xml_document.ImportNode(copy_node, true); // Next locate which node should be its parent, and // insert it string xpath_query = buildXPathQuery(this.SelectedNode); System.Xml.XmlNode node = xml_document.DocumentElement.SelectSingleNode( xpath_query); node.AppendChild(insert_node); // Finally, apply the xpath filter to determine what // to display System.Xml.XmlNode expr = insert_node.SelectSingleNode(xpath_filter); System.Windows.Forms.TreeNode new_child = SelectedNode.Nodes.Add(expr.Value); populateTreeControl(insert_node, new_child.Nodes); // Select the node, to force the tree to expand SelectedNode = new_child; // And start editing the new folder name suppress_label_edit = false; new_child.BeginEdit();


[VB] ' First you need to clone the node template, and ' import it, because it originates from a different ' document. Dim copy_node As System.Xml.XmlNode = new_node.Clone() Dim insert_node As System.Xml.XmlNode = _ xml_document.ImportNode(copy_node, True) ' Next locate which node should be its parent, ' and insert it Dim xpath_query As String = _ buildXPathQuery(Me.SelectedNode) Dim node As System.Xml.XmlNode = xml_document.DocumentElement.SelectSingleNode( _ xpath_query) node.AppendChild(insert_node) ' Finally, apply the xpath filter to determine what ' should be ' displayed Dim expr As System.Xml.XmlNode = _ insert_node.SelectSingleNode(xpath_filter) Dim new_child As System.Windows.Forms.TreeNode = _ SelectedNode.Nodes.Add(expr.Value) populateTreeControl(insert_node, new_child.Nodes) ' Select the node, to force the tree to expand SelectedNode = new_child ' And start editing the new folder name suppress_label_edit = False new_child.BeginEdit()



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date