如何使用Microsoft.Web.UI.TreeView
Microsoft.Web.UI.TreeView是微软发布的一个用于显示树型结构的WEB Control,他的用处相信大家都已经很清楚了。
我这里主要介绍它的使用方法,以及进行数据帮定的办法
微软的这个TreeView是一个ServerControl,运行在服务器端,在使用的时候必需要进行注册。
首先引入名字空间:
<%@ import namespace="Microsoft.Web.UI.WebControls" %>
然后进行注册:
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls,
Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
这个命令是用来注册自定义控件的,具体含义可以查看msdn.
注册以后就可以在页面中使用了。TreeView使用TreeNode子标记来定义其中的节点,如下面的格式:
<form runat="server">
<iewc:Treeview>
<treenode text = "Parent1" runat="server">
<treenode text="child1"/>
<treenode text="child2"/>
<treenode text="child3"/>
</treenode>
<treenode text = "parent2">
<treenode text="child4"/>
<treenode text="child5"/>
<treenode text="child6"/>
</treenode>
</iewc:Treeview>
</form>
另一个比较有用的标记是<TreeNodeType>,这个标记可以用来定义显示节点的格式。例如,在默认的情况下,TreeView控件采用"+","-"那样的
图标来表示某一个节点是否处于展开状态,但是你可以使用TreeNodeType的ExpandImageUrl属性来自己定义展开后需要显示的图片,使用
imageUrl指定关闭时的图标。例:
<form id="myform" runat="server">
<mytree:treeview runat="server" ChildType="Folder">
<mytree:treenodetype Type="Folder"
ExpandedImageUrl="./images/folderopen.gif"
ImageUrl="./images/folder.gif" />
<mytree:treenode Text="Michigan">
<mytree:treenode Text="Detroit" />
<mytree:treenode Text="Farmington" />
<mytree:treenode Text="Southfield" />
</mytree:treenode>
<mytree:treenode Text="Washington" >
<mytree:treenode Text="Bellevue" />
<mytree:treenode Text="Redmond" />
<mytree:treenode Text="Woodinville" />
</mytree:treenode>
</mytree:treeview>
</form>
在你显示这个TreeView的时候你就可以发现,所有节点前面的图标已经变成了你自己定义的图标了。假如你希望第一层采用文件夹的打开关闭
样式的图标,第二层则采用类似于文件一样的图标,则可以使用childtype这样的属性来定制,例:
<form id="myform" runat="server">
<mytree:treeview runat="server" ChildType="Folder">
<mytree:treenodetype Type="Folder"
ChildType="file"
ExpandedImageUrl="./images/folderopen.gif"
ImageUrl="./images/folder.gif" />
<mytree:treenodetype Type="file"
ImageUrl="./images/file.gif" />
<mytree:treenode Text="Michigan">
<mytree:treenode Text="Detroit" />
<mytree:treenode Text="Farmington" />
<mytree:treenode Text="Southfield" />
</mytree:treenode>
<mytree:treenode Text="Washington" >
<mytree:treenode Text="Bellevue" />
<mytree:treenode Text="Redmond" />
<mytree:treenode Text="Woodinville" />
</mytree:treenode>
</mytree:treeview>
</form>
然后显示这个treeview,你会发现第一层的图标仍然是folder,第二层的图标则全部变成了file。依照这样的方式,你还可以定义第三层第四
层,只要使用childtype同Type进行对应一层层嵌套下去就可以了。
TreeView控件有三个属性可以用来使用css定义节点的格式,DefaultStyle,HoverStyle,SelectedStyle,看名字就可以知道大概的意思,不作具
体介绍了。
下面说一下treeview的数据帮定问题。
TreeView控件的数据帮定只能帮定到xml文件或者包含xml内容的字符串上去。被绑定的字符串或者文件必须采用如下格式:
<TREENODES>
<TREENODE TEXT="NODE1" />
<TREENODES>
在文件或者字符串中,大小写是敏感的,所以你必须使用全部大写的TREENODES标记把所有的节点标记包围起来,内部的节点标记则只要是前后
大小写一致就可以了。
然后把这个文件的url或者字符串赋值给TreeView或者TreeNode标记的TreeNodeSrc属性就可以了。使用codebehind模式的兄弟们需要注意,不
能在page_onload事件中指定这个属性,那样什么都显示不出来。
当然也可以利用sql server 2K提供的xml支持功能直接把TreeView同数据库中有层次关系的数据帮定起来。有两种方法可以选择:
一种方法是使用sql server 2k提供的web查询方式,返回一个xml字符串流,例:
<ie:treenode Text="root" type="tree" Expanded="true"
TreeNodeSrc="http://localhost/mySQLXML?sql=execute+sp_GenMyXML+@pid=1" />
但是这样做就必须还要创建一个xsl文件来把所获得的结果转换成TreeView可以接受的形式,也就是说里面只能包含<TREENODES>和<TreeNode>
两种标记。
另一种方法是直接采用sql server 2k提供的for xml子句来完成这个功能。你可以使用for xml子句的explicit命令来手动指定返回的xml中的
层次集合以及标记名称。我自己写了一个例子,用的是sql server 2k自带的NorthWind数据库:
SELECT 1as Tag,
NULL as Parent,
Customers.CompanyName as [TREENODE!1!Text],
NULL as [TREENODE!2!Text],
Nullas [TREENODE!2!NodeData]
FROM Customers
UNION ALL
SELECT 2,
1,
Customers.companyName,
Orders.OrderID,
[Order Details].Quantity
FROM Customers, Orders,[Order Details]
WHERE Customers.CustomerID = Orders.CustomerID and [Order Details].OrderID = Orders.OrderID
ORDER BY [TREENODE!1!Text], [TREENODE!2!Text]
FOR XML EXPLICIT
具体含义看sql server 的book online对for xml子句以及explicit命令的详细说明。
我们可以首先创建一个叫做NodeSource.aspx的文件,在这个文件中,使用SqlCommand的ExecuteXmlReader方法进行执行上面的sql 语句,返回
一个XmlReader对象,把xmlReader对象的内容做为输出。
然后指定一个treeview对象的TreeNodeSrc属性到这个文件的URL就可以了。
NodeSource.aspx文件示例如下:
public class NodeSource : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
String connectionString = "server=server;uid=sa;pwd=;database=northwind";
System.Data.SqlClient.SqlConnection connection = new
System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "GetXML";//包含上述Sql 语句的存储过程
command.CommandType = System.Data.CommandType.StoredProcedure;
System.Data.SqlClient.SqlDataAdapter sa= new System.Data.SqlClient.SqlDataAdapter(command);
connection.Open();
System.Xml.XmlReader xml = command.ExecuteXmlReader();
xml.Read();
Response.ContentType = "text/xml";
Response.Output.Write("<TREENODES><TREENODE text='parent'>" + xml.ReadOuterXml().Replace("\"","'") +
"</TREENODE></TREENODES>");
}
最后,说一下对TreeView WebControl的感觉,这个东东在设定autopostback=false的时候倒是还蛮好用的,但是如果设置autopostback=true,
那么就会闪的厉害,每次点击一个节点,都会刷新一边,然后重新定位到某个节点。但是如果不设定autopostback=true,则无法使用treeview
控件自己带的三个事件:Expand、Collapse、selectedIndexChanged。比较郁闷。但是利用一些客户端的教本以及msxml差不多可以实现不刷新
的TreeView控件,这些等下次再说吧。
……