TreeView is a visually compelling way to represent information that Microsoft uses constantly. The first article in this series showed the basic TreeView in Windows forms and WPF as well as two examples (VB code and HTML) for ASP.NET.
Like the Windows forms version, ASP.NET TreeView controls can be created declaratively (design time) or dynamically (run time). And like all ASP.NET, the declarative version can be created in a visual designer window or manually with ASP.NET HTML code.
The ASP.NET version of TreeView leaves the Windows forms version in the dust when it comes to features. For example, in contrast to Windows forms, icons can be just about whatever you want and colors and borders can be too. You can go nuts with this and produce something bizzare. In the illustration below, in addition to the random borders, colors and fonts, ExpandImageUrl points to the "devil horn dog", CollapseImageUrl points to "angel dog" and NoExpandImageUrl points to "dragon cat". Yours Truly is the icon set for just the Parent node and that node also has a CheckBox shown.
--------
Click Here to display the llustration
--------
You can also use CSS formatting in a variety of ways, although this gets us into the tangled snarl of HTML coding. Trust me on this: Not everything you try using ASP.NET objects in HTML is going to work and you can lose days of time just trying to figure out why not. Because the default in HTML is to simply "not work" without triggering an exception for the convenience of the user, there's usually not much information to help you figure out why it's not doing what you want. I recommend simply using what works and moving on rather than trying to debug ASP.NET objects in HTML.
As an example of CSS formatting in ASP.NET, I added this style to the built-in Site.css file.
.AboutVB
{
background-image: url(..\Expand.jpg);
font-weight: bold;
font-size: large;
}
This coding in the TreeView element of the ASP.NET source then produces the result in the illustration below:
<asp:TreeView ID="TreeView1" runat="server"
Height="200px" Width="400px"
CssClass="AboutVB">
</asp:TreeView>
--------
Click Here to display the llustration
--------
If you search for information about TreeView on the web, there are points of confusion that don't get much of an explanation at the Microsoft site. In fact, it seems to me that they add to the confusion.
The first point of confusion is that there are two namespaces to choose from for the ASP.NET TreeView control. Microsoft originally introduced it in a separate download in the Microsoft.Web.UI.WebControls namespace. In Framework 4.0 (the version used in this article), that namespace isn't included or supported. In spite of this, Microsoft continues to have dozens of pages at their site that give you detailed instructions for adding it to your project and using it, without ever mentioning that System.Web.UI.WebControls is the supported version. I congratulate Microsoft for giving us the documentation for backward compatibility, but Microsoft pages don't make it clear how to make forward progress.
This is partly due to the fact that if you create a new ASP.NET project in Visual Studio 2010, you get System.Web (which includes System.Web.UI.WebControls) completely automatically so any instructions about referencing the a namespace in your project are unnecessary. But if you then search for "ASP.NET" and "TreeView" you will get a lot of confusing pages which do explain the old namespace that won't help you. The bottom line: Pay attention to precisely what is being documented. Especially in this case, it makes a difference.
Since XML and a TreeView are close to the same thing logically, populating a TreeView from an XML file is easy. Just add an XMLDataSource control to your project and configure it to point to an XML data file containing the TreeView nodes you want. I added a file named myXMLTreeView.xml to the project. (Right-click, Add, New Item... In the Data templates, add an XML File.)
<?xml version="1.0" encoding="utf-8" ?>
<Parent>
<Child1 />
<Child2>
<GrandChild>
<GreatGrandChild />
</GrandChild>
</Child2>
</Parent>
Then configure the properties of the XMLDataSource control like this:
<asp:XmlDataSource ID="XmlDataSource1" runat="server"
DataFile="~/myXMLTreeView.xml"></asp:XmlDataSource>
The result is exactly the same as previous illustrations but that doesn't make it "right". (One fact that has always helped me understand why XML works the way it does: XML is a language that was designed by a committee. Truth!!)
The first article in this series shows how to populate a TreeView with static data from XML and the XML I used there is quite different.
<asp:TreeView ID="TreeView1"
ExpandDepth="FullyExpand" runat="server"
Height="175px" Width="336px">
<Nodes>
<asp:TreeNode Text="Parent">
<asp:TreeNode Text="Child 1" />
<asp:TreeNode Text="Child 2">
<asp:TreeNode Text="Grandchild">
<asp:TreeNode
Text="Great Grandchild" />
</asp:TreeNode>
</asp:TreeNode>
</asp:TreeNode>
</Nodes>
</asp:TreeView>
The big difference is the prefix: "asp:". This indicates the namespace for the control. As noted earlier, all the standard ASP.NET controls are contained in the System.Web.UI.WebControls namespace. The tag prefix "asp:" represents this namespace in the current version of Framework. When you use the first XML example above, the XML is rendered strictly on the client and Visual Studio is smart enough to provide Javascript to do the work (expanding or collapsing the nodes) on the client. But you get none of the advantages of ASP.NET. The second example lets you use ASP.NET methods and properties too.
To work correctly, the second XML example above has to be part of the .aspx file so it can be processed by the server; it can't be in a separate file. But you will usually want to load your XML from a file rather than have it in the program source. Here's an ASP.NET code snippet that you can put in your .aspx file to do that. (Remember, this uses the first non-asp prefixed XML.)
<asp:TreeView ID="TreeView1" runat="server"
Height="200px" Width="400px"
DataSourceID="XMLSource">
<DataBindings>
<asp:TreeNodeBinding
DataMember="Parent"
Text="Parent" />
</DataBindings>
</asp:TreeView>
--------
Click Here to display the llustration
--------
ASP.NET gives you a wide choice of methods and properties that you can use with your XML file. For example, suppose you want to use names to identify the nodes. I've used the geneology in the Bible and added a Name attribute.
<Parent Name="Adam" >
<Child Name="Abel" />
<Child Name="Cain">
<GrandChild Name="Enoch">
<GreatGrandChild Name="Irad" />
</GrandChild>
</Child>
</Parent>
Then this aspx coding will produce the results shown in the illustration below:
<asp:TreeView ID="TreeView1"
runat="server" DataSourceID="XMLSource">
<DataBindings>
<asp:TreeNodeBinding
DataMember="Parent"
TextField="Name" />
<asp:TreeNodeBinding
DataMember="Child"
TextField="Name" />
<asp:TreeNodeBinding
DataMember="GrandChild"
TextField="Name" />
<asp:TreeNodeBinding
DataMember="GreatGrandChild"
TextField="Name" />
</DataBindings>
</asp:TreeView>
--------
Click Here to display the llustration
--------
Although there are many, many ways to do it, one way to update your XML using VB.NET code is shown below. After a node is clicked, the Button changes the Name attribute in that node to "George". (To keep things simple, didn't add the code to prevent this app from crashing if no node is selected first.)
Protected Sub Button1_Click(
ByVal sender As Object,
ByVal e As EventArgs
) Handles Button1.Click
Dim myXml As New XmlDocument
myXml =
CType(XMLSource.GetXmlDocument(), XmlDocument)
Dim iterator As String =
TreeView1.SelectedNode.DataPath
Dim myNode As XmlNode =
myXml.SelectSingleNode(iterator)
myNode.Attributes("Name").Value = "George"
XMLSource.Save()
TreeView1.DataBind()
TreeView1.ExpandAll()
End Sub
