基于ComponentArt.Web.UI Tree控件封装的自定义用户控件TreeListBox

  

控件说明

     先看一张控件的效果图,这个控件的左边是一个树形结构的数据源,右边则是选中节点的列表

选中后效果如下

 

 1)、树形数据源可以支持DataSet,DataTable,DataView,IEnumerable,XML

 2)、数据源加载方式 提供Ajax加载 Xml 自动绑定 和 递归载入  ,具体使用方式见下方介绍

 3)、取值和赋值方式都提供服务端和客户端方式

其他一些属性在源代码中都有详细的注释...

注意:IEnumerable必须是一个对象实体集合,不支持string[] ,List<string>这种类型 

TreeListBox源代码下载地址

使用方式

1、数据源绑定至树

  1)、XML数据源

XML数据源示例
<siteMap>
<siteMapNode Text="MSDN Library" Value="1">
<siteMapNode Text="How to Use the MSDN Library" Value="2"/>
</siteMapNode>
<siteMapNode Text="Component Development" Value="3">
<siteMapNode Text="ActiveX Controls" Value="4">
<siteMapNode Text="SDK Documentation" Value="5">
<siteMapNode Text="Security Considerations" Value="6" />
<siteMapNode Text="Overviews / Tutorials" Value="7"/>
<siteMapNode Text="Reference" Value="1" />
<siteMapNode Text="Internet Development" Value="8"/>
</siteMapNode>
<siteMapNode Text="Technical Articles" Value="100">
<siteMapNode Text="The ABCs of MFC ActiveX Controls" Value="9"/>
<siteMapNode Text="ADODB: ActiveX Data Objects 2.1" Value="10"/>
<siteMapNode Text="Creating a Slide Show Using the ActiveX Timer Control" Value="11"/>
<siteMapNode Text="Creating an ActiveX Control to Access the IntelliMouse" Value="12"/>
</siteMapNode>
</siteMapNode>
<siteMapNode Text="Automation" Value="13" >
<siteMapNode Text="SDK Documentation">
<siteMapNode Text="Security Considerations" Value="14" />
<siteMapNode Text="Overviews / Tutorials" Value="15" />
<siteMapNode Text="Reference" Value="17" />
<siteMapNode Text="Internet Development" Value="16"/>
</siteMapNode>
</siteMapNode>
</siteMapNode>
<test NotInPath="true" Selectable="false" ToolTip="不能选择" Text="我是不能选择的且不在路径中" >
<test Text="a" Value="1"></test>
</test>
</siteMap>

  将TreeListBox控件拖至使用的页面

    <%@ Register Src="~/Controls/TreeListBox.ascx" TagName="TreeListBox" TagPrefix="uc1" %>
<!--设置数据绑定方式为SiteMapXml 然后指定XML的位置-->
<uc1:TreeListBox ID="TreeListBox1" runat="server" RunningMode="SiteMapXml" SiteMapXmlFile="~\Data\treeData.xml" />

  2)、DataTable数据源

  

DataTableDemo.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DataTableDemo.aspx.cs" Inherits="Examples_DataTableDemo" %>

<%@ Register Src="../Controls/TreeListBox.ascx" TagName="TreeListBox" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:TreeListBox ID="TreeListBox1" runat="server" TextField="Text" ValueField="Value" />
</div>
</form>
</body>
</html>

  

DataTableDemo.aspx.cs
using System;
using System.Data;
/// <summary>
/// DataTable Demo
/// </summary>
public partial class Examples_DataTableDemo : System.Web.UI.Page {

#region "私有成员"

private DataTable oDataTable = null;

#endregion

#region "页面事件"

//页面初始化
protected void Page_Init(object sender, EventArgs e) {
TreeListBox1.NeedDataSource
+= new Controls_TreeListBox.NeedDataSourceHandler(TreeListBox1_NeedDataSource);
}
//页面载入
protected void Page_Load(object sender, EventArgs e) {
InitTestDataTable();
}
//绑定数据源
protected object TreeListBox1_NeedDataSource(object oParentKey) {
return GetDataTable(oParentKey);
}

#endregion

#region "私有方法"
/// <summary>
/// 初始化测试DataTable
/// </summary>
private void InitTestDataTable() {
if (oDataTable == null)
oDataTable
= CreateEmptyDataTable();
else
oDataTable.Clear();
DataRow row
= oDataTable.NewRow();
row[
"Text"] = "第一级";
row[
"Value"] = 1;
row[
"ParentId"] = 0;

DataRow row2
= oDataTable.NewRow();
row2[
"Text"] = "第二级1";
row2[
"Value"] = 3;
row2[
"ParentId"] = 1;

DataRow row3
= oDataTable.NewRow();
row3[
"Text"] = "第二级2";
row3[
"Value"] = 4;
row3[
"ParentId"] = 1;

oDataTable.Rows.Add(row);
oDataTable.Rows.Add(row2);
oDataTable.Rows.Add(row3);
}
/// <summary>
/// 创建一个空的DataTable
/// </summary>
/// <returns>DataTable</returns>
private DataTable CreateEmptyDataTable() {
DataTable oDataTable
= new DataTable();
oDataTable.Columns.Add(
"Text");
oDataTable.Columns.Add(
"Value");
oDataTable.Columns.Add(
"ParentId");
return oDataTable;
}
/// <summary>
/// 根据ParentId获取DataTable
/// </summary>
/// <param name="oParentId">父ID</param>
/// <returns>DataTable</returns>
private DataTable GetDataTable(object oParentId) {
DataTable newDt
= CreateEmptyDataTable();
DataRow[] rows
= oDataTable.Select("ParentId=" + oParentId);
foreach (DataRow item in rows) {
newDt.ImportRow(item);
}
return newDt;
}

#endregion
}

  3)、IEnumerable数据源

IEnumerableDemo.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="IEnumerableDemo.aspx.cs" Inherits="Examples_IEnumerableDemo" %>

<%@ Register Src="../Controls/TreeListBox.ascx" TagName="TreeListBox" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<!--
注意这个Demo只是测试数据,RunningMode不能设置Recursive否则会死循环
AllowShowRootNodeInPath=false 根节点不显示在选中的路径
RootNodeText 根节点文本
RootNodeValue 根节点值
-->
<uc1:TreeListBox ID="TreeListBox1" runat="server" TextField="Text" ValueField="Value" RunningMode="Callback" RootNodeText="根节点" RootNodeValue="0" AllowShowRootNodeInPath="false" />
</div>
</form>
</body>
</html>

  

IEnumerableDemo.aspx.cs
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
/// <summary>
/// IEnumerable Demo
/// </summary>
public partial class Examples_IEnumerableDemo : System.Web.UI.Page {

#region "页面事件"

//初始化点击
protected void Page_Init(object sender, EventArgs e) {
TreeListBox1.NeedDataSource
+= new Controls_TreeListBox.NeedDataSourceHandler(TreeListBox1_NeedDataSource);
}
//这里每点击一个次节点会传递当前节点Value,初始值为0 ---(oParentKey)
protected object TreeListBox1_NeedDataSource(object oParentKey) {
return GetTestListItemCollection(oParentKey);
}

#endregion

#region "私有方法"

//模拟测试数据
private List<ListItem> GetTestListItemCollection(object oParentKey) {
List
<ListItem> lstItems = new List<ListItem>();
for (int i = 1; i < 10; i++) {
lstItems.Add(
new ListItem(string.Format("ParentValue {0} Text {1}", oParentKey, i.ToString()), (i.ToString() + oParentKey)));
}
return lstItems;
}

#endregion
}

2、获取和设置选中的值 

服务端取值和赋值以及事件
//页面载入
protected void Page_Load(object sender, EventArgs e) {
TreeListBox1.AfterNodeDataBound
+= new Controls_TreeListBox.AfterNodeDataBoundHandler(TreeListBox1_AfterNodeDataBound);
TreeListBox1.BeforeNodeDataBound
+= new Controls_TreeListBox.BeforeNodeDataBoundHandler(TreeListBox1_BeforeNodeDataBound);
TreeListBox1.NeedDataSource
+= new Controls_TreeListBox.NeedDataSourceHandler(TreeListBox1_NeedDataSource);
if (!IsPostBack) {
//赋值初始值
TreeListBox1.SelectedValue = "100";
TreeListBox1.SelectedText
= "Component Development>ActiveX Controls>Technical Articles ";
TreeListBox1.DataBind();
}
}
//节点绑定数据前
protected bool TreeListBox1_BeforeNodeDataBound(ComponentArt.Web.UI.TreeViewNode oTreeNode, object oDataItem) {

string sUserRight = TreeListBox1.GetObjectValue(oDataItem, "UserRight", "");
if (sUserRight != "N") {//如果属性值不为N 返回false 则不向树种添加此节点,可以用做权限的判断
return false;
}
return true;
}
//节点绑定数据后
protected void TreeListBox1_AfterNodeDataBound(ComponentArt.Web.UI.TreeViewNode oTreeNode, object oDataItem) {

//获取当前正在绑定的数据项Value的属性值
string sValue = TreeListBox1.GetObjectValue(oDataItem, "Value", "");

//绑定一个自定义的属性
oTreeNode.Attributes["Name"] = TreeListBox1.GetObjectValue(oDataItem, "Name", "");

Response.Write(sValue
+ "<br/>");

}
//绑定数据(非XML数据源必须实现该事件)
protected object TreeListBox1_NeedDataSource(object oParentKey) {
throw new NotImplementedException();
//可以参考上面的Demo
}


protected void btnServerTest1_Click(object sender, EventArgs e) {
//取选中值方式1
Response.Write(string.Format(@"选中值:{0}<br/>选中文本:{1}", TreeListBox1.SelectedValue, TreeListBox1.SelectedText));
}

protected void btnServerTest2_Click(object sender, EventArgs e) {
//取选中值方式2
foreach (var item in TreeListBox1.SelectedItems) {
Response.Write(
"值:" + item.Value + ",文本:" + item.Text + @"<br/>");
}
}

  

客户端取值和赋值以及事件
  <uc1:TreeListBox ID="TreeListBox1" runat="server" RunningMode="SiteMapXml" SiteMapXmlFile="~\Data\treeData.xml" />
<asp:Button runat="server" ID="btnServerTest1" Text="服务端取值方式1" />
<asp:Button runat="server" ID="btnServerTest2" Text="服务端取值方式2" />
<asp:Button runat="server" ID="btnClientGetValue" Text="客户端取值" />
<asp:Button runat="server" ID="btnClientSetValue" Text="客户端赋值" /><br />
<script type="text/javascript">
$(document).ready(
function () {
//取值
$("#btnClientGetValue").click(function () {
var message = "选中值:" + TreeListBox1.getSelectedValue() + "\n选中文本:" + TreeListBox1.getSelectedText();
alert(message);
return false;
});
//赋值
$("#btnClientSetValue").click(function () {
TreeListBox1.setSelectedItem(
"Component Development", 3);
return false;
});

//TreeListBox1.addEvent("BeforeAddItem", function (e) {
// alert("触发BeforeAddItem\n" + e.Text);
//});
//TreeListBox1.addEvent("AfterAddItem", function (e) {
// alert("触发AfterAddItem\n" + e.Value);
//});
//TreeListBox1.addEvent("BeforeRemoveItem", function (e) {
// alert("触发BeforeRemoveItem\n" + e.Text);
//});
//TreeListBox1.addEvent("AfterRemoveItem", function (e) {
// alert("触发AfterRemoveItem\n" + e.Text);
//});
//TreeListBox1.addEvent("BeforeRemoveAllItem", function () {
// alert("触发BeforeRemoveAllItem\n");
//});
//TreeListBox1.addEvent("AfterRemoveAllItem", function () {
// alert("触发AfterRemoveAllItem\n");
//});
TreeListBox1.addEvent("select", function (e) {
alert(
"触发Select\n" + e.Text);
});
TreeListBox1.addEvent(
"cancel", function (e) {
alert(
"触发Cancel\n");
});
});
</script>

  

      注意: 一个面中若有多个TreeListBox控件且采用Postback方式提交取值存在BUG ,目前还没解决.不过采用Ajax提交是正常的  

 TreeListBox源代码下载地址

posted @ 2011-08-15 22:15  昔日醉离愁  阅读(676)  评论(0编辑  收藏  举报