要想做到treeview在客户端的操作的话,首先要了解treeview生成的html,比如下面一个 treeview
它的每一个节点生成的html都是一个table,比如说根节点
<
table
cellpadding
="0"
cellspacing
="0"
style
="border-width:0;"
>
< tr >
< td >< a id ="TreeView1n0" href ="javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,' ',TreeView1n0Nodes)" >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJehFROhg3KOcfwktkbcd1USw1&t=633087263926406250" alt ="折叠 根节点" style ="border-width:0;" /></ a ></ td >< td class ="TreeView1_1" style ="white-space:nowrap;" >< span class ="TreeView1_0" id ="TreeView1t0" > 根节点 </ span ></ td >
</ tr >
</ table >
< tr >
< td >< a id ="TreeView1n0" href ="javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,' ',TreeView1n0Nodes)" >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJehFROhg3KOcfwktkbcd1USw1&t=633087263926406250" alt ="折叠 根节点" style ="border-width:0;" /></ a ></ td >< td class ="TreeView1_1" style ="white-space:nowrap;" >< span class ="TreeView1_0" id ="TreeView1t0" > 根节点 </ span ></ td >
</ tr >
</ table >
可以看到节点的文本是放在一个id为"TreeView1t0"的span里面的,但是从这里不能取得节点的值(这 个问题一会儿解决),再来看它的子节点的html。
<
div
id
="TreeView1n0Nodes"
style
="display:block;"
>
< table cellpadding ="0" cellspacing ="0" style ="border-width:0;" >
< tr >
< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< a id ="TreeView1n1" href ="javascript:TreeView_ToggleNode(TreeView1_Data,1,TreeView1n1,' ',TreeView1n1Nodes)" >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJehFROhg3KOcfwktkbcd1USw1&t=633087263926406250" alt ="折叠 aaa" style ="border-width:0;" /></ a ></ td >< td style ="white-space:nowrap;" >< span class ="TreeView1_0" id ="TreeView1t1" > aaa </ span ></ td >
</ tr >
</ table >< div id ="TreeView1n1Nodes" style ="display:block;" >
< table cellpadding ="0" cellspacing ="0" style ="border-width:0;" >
< tr >
< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJeox2LqmFZnR_zUU0BO2r0tM1&t=633087263926406250" alt ="" /></ td >< td style ="white-space:nowrap;" >< span class ="TreeView1_0" href ="27" id ="TreeView1t2" > a1 </ span ></ td >
</ tr >
</ table > …….
< table cellpadding ="0" cellspacing ="0" style ="border-width:0;" >
< tr >
< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< a id ="TreeView1n1" href ="javascript:TreeView_ToggleNode(TreeView1_Data,1,TreeView1n1,' ',TreeView1n1Nodes)" >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJehFROhg3KOcfwktkbcd1USw1&t=633087263926406250" alt ="折叠 aaa" style ="border-width:0;" /></ a ></ td >< td style ="white-space:nowrap;" >< span class ="TreeView1_0" id ="TreeView1t1" > aaa </ span ></ td >
</ tr >
</ table >< div id ="TreeView1n1Nodes" style ="display:block;" >
< table cellpadding ="0" cellspacing ="0" style ="border-width:0;" >
< tr >
< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< div style ="width:20px;height:1px" ></ div ></ td >< td >< img src ="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJeox2LqmFZnR_zUU0BO2r0tM1&t=633087263926406250" alt ="" /></ td >< td style ="white-space:nowrap;" >< span class ="TreeView1_0" href ="27" id ="TreeView1t2" > a1 </ span ></ td >
</ tr >
</ table > …….
它的子节点都是放在一个id为"TreeView1n0Nodes"的div里面的,再来看aaa节点的子节点,也 是放在"TreeView1n1Nodes",而aaa节点的span的id为"TreeView1t1"。这样整个treeview的html的结构就 清楚了。
再说明一点,注意看根节点的html
<
td
class
="TreeView1_1"
style
="white-space:nowrap;"
><
span
class
="TreeView1_0"
id
="TreeView1t0"
>
根节点
</
span
></
td
>
主要是class="TreeView1_1",这个是TreeView1_1的样式表是treeview设置 了SelectedNodeStyle属性生成的,html代码如下
<
style
type
="text/css"
>
.TreeView1_0 { text-decoration : none ; }
.TreeView1_1 { background-color : #E0E0E0 ; border-color : #E0E0E0 ; border-width : 1px ; border-style : Solid ; }
</ style >
.TreeView1_0 { text-decoration : none ; }
.TreeView1_1 { background-color : #E0E0E0 ; border-color : #E0E0E0 ; border-width : 1px ; border-style : Solid ; }
</ style >
如果节点被选择的话,节点所在的td的class属性就会被设置为TreeView1_1。
最后说明一点,页面生成的html里还有这个
< input type ="hidden" name ="TreeView1_SelectedNode" id ="TreeView1_SelectedNode" value ="TreeView1t0" />
这里面放的是被选中的节点所在的span的id。
搞清楚以上几点,就可以看具体是怎么做的了,首先是treeview控件的代码
< asp:TreeView ID ="TreeView1" runat ="server"
OnTreeNodePopulate ="TreeView1_TreeNodePopulate" EnableViewState ="False" >
< SelectedNodeStyle BorderColor ="#E0E0E0" BorderStyle ="Solid" BorderWidth ="1px" BackColor ="#E0E0E0" />
< Nodes >
< asp:TreeNode PopulateOnDemand ="True" SelectAction ="None" Selected ="True" Text ="根节点" Value ="0" ></ asp:TreeNode >
</ Nodes >
</ asp:TreeView >
OnTreeNodePopulate ="TreeView1_TreeNodePopulate" EnableViewState ="False" >
< SelectedNodeStyle BorderColor ="#E0E0E0" BorderStyle ="Solid" BorderWidth ="1px" BackColor ="#E0E0E0" />
< Nodes >
< asp:TreeNode PopulateOnDemand ="True" SelectAction ="None" Selected ="True" Text ="根节点" Value ="0" ></ asp:TreeNode >
</ Nodes >
</ asp:TreeView >
我要用的是TreeNodePopulate方法来绑定数据,所以上面先加一个根节点,值为0,注意一点要把 PopulateOnDemand属性设置为True。
然后再来看后台代码
protected
void
Page_Load(
object
sender, EventArgs e)
{
if (Request.QueryString[ " id " ] != null )
{
OleDbConnection conn = new OleDbConnection( " Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + Server.MapPath( " ~/App_Data/Database1.mdb " ));
OleDbCommand cmd = new OleDbCommand( " delete from tree where id = " + Request.QueryString[ " id " ], conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Response.Write( " 0 " );
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
Response.End();
}
}
{
if (Request.QueryString[ " id " ] != null )
{
OleDbConnection conn = new OleDbConnection( " Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + Server.MapPath( " ~/App_Data/Database1.mdb " ));
OleDbCommand cmd = new OleDbCommand( " delete from tree where id = " + Request.QueryString[ " id " ], conn);
try
{
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Response.Write( " 0 " );
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
Response.End();
}
}
这个是删除节点的代码,初学者也能看明白,但为什么这样写一会儿看ajax方法就知道了
protected
void
TreeView1_TreeNodePopulate(
object
sender, TreeNodeEventArgs e)
{
OleDbConnection conn = new OleDbConnection( " Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + Server.MapPath( " ~/App_Data/Database1.mdb " ));
OleDbCommand cmd = new OleDbCommand( " select * from tree where parentid = " + e.Node.Value, conn);
TreeNode newNode;
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
newNode = new TreeNode();
newNode.Text = dr[ 1 ].ToString();
newNode.Value = dr[ 0 ].ToString();
newNode.PopulateOnDemand = true ;
newNode.NavigateUrl = dr[ 0 ].ToString();
newNode.SelectAction = TreeNodeSelectAction.None;
e.Node.ChildNodes.Add(newNode);
}
dr.Close();
conn.Close();
}
{
OleDbConnection conn = new OleDbConnection( " Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + Server.MapPath( " ~/App_Data/Database1.mdb " ));
OleDbCommand cmd = new OleDbCommand( " select * from tree where parentid = " + e.Node.Value, conn);
TreeNode newNode;
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
newNode = new TreeNode();
newNode.Text = dr[ 1 ].ToString();
newNode.Value = dr[ 0 ].ToString();
newNode.PopulateOnDemand = true ;
newNode.NavigateUrl = dr[ 0 ].ToString();
newNode.SelectAction = TreeNodeSelectAction.None;
e.Node.ChildNodes.Add(newNode);
}
dr.Close();
conn.Close();
}
Treeview的绑定代码,数据库的结构很简单,就是id,classname,parentid三个字 段,parentid表示父节点的id。相信用过treeview的朋友应该能看懂上面的代码,主要是上面红色的部分,这样做就可以让节点所在的span 生成href属性,属性值为节点的值。这样我们在客户端就可以取到节点值了。
接下来是客户端选择节点的代码,当然是javascript,不过本人的javascript学的不精,幸好前 一段时间研究了一下jquery这个好东西。所以下面的代码都是用jquery实现的(jquery的具体语法看这里
http://jquery.org.cn/
,我不对语法做具体说明了,只说明语句作用)
$(
"
span
"
).click(
function
()
{
var selected = " # " + $( " #TreeView1_SelectedNode " ).val(); // 上一次选择的节点的id
$(selected).parent().attr( " class " , "" ); // 去掉上一次选择的节点的选择样式
$( this ).parent().attr( " class " , " TreeView1_1 " ); // 给新选择的节点加上选择样式
$( " #TreeView1_SelectedNode " ).val( this .id) // 把新选择的节点的id放到id为TreeView1_SelectedNode隐藏域
$( " #selectedvalue " ).val($( " # " + this .id).attr( " href " )); // 把新选择的节点的值放到id为selectedvalue文本框里
} );
var selected = " # " + $( " #TreeView1_SelectedNode " ).val(); // 上一次选择的节点的id
$(selected).parent().attr( " class " , "" ); // 去掉上一次选择的节点的选择样式
$( this ).parent().attr( " class " , " TreeView1_1 " ); // 给新选择的节点加上选择样式
$( " #TreeView1_SelectedNode " ).val( this .id) // 把新选择的节点的id放到id为TreeView1_SelectedNode隐藏域
$( " #selectedvalue " ).val($( " # " + this .id).attr( " href " )); // 把新选择的节点的值放到id为selectedvalue文本框里
} );
注释已经很清楚了,不再多说。
下面是最重要的删除部分,所用的ajax方法也是jquery自带的(jquery真是越用越顺手),
$(
"
#delNode
"
).click(
function
()
{
var selected = document.getElementById($( " #TreeView1_SelectedNode " ).val()); // 取得选择的节点
if (selected != null )
{
// 调用jquery的ajax方法删除节点
$.ajax( {
type: " get " ,
dataType: " text " ,
url: " treeview.aspx " ,
data: " id= " + $( " #selectedvalue " ).val(),
success: function (msg) {
if (msg == " 0 " ) // 删除成功
DelNode(selected); // 删除页面上相应的节点
else
alert(msg);
}
} );
}
else
alert( " 请先选择节点 " );
} );
function DelNode(node)
{
var subdiv = " # " + node.id.replace( " t " , " n " ) + " Nodes " ; // 节点的子节点所在div的id
if ($(subdiv).html() == null ) // 没有子节点
{
if ($(WebForm_GetParentByTagName(node, " div " )).find( " table " ).length == 1 ) // 这个用来判断是否有兄弟节点
{
// 如果只有一个节点,没有其他兄弟节点的话,就需要把这个节点所在的div一起删掉
var parentdiv = WebForm_GetParentByTagName(node, " div " )
$(parentdiv).remove();
$( " # " + parentdiv.id.replace( " t " , " n " ).replace( " Nodes " , "" )).parent().html( " <img src="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJeox2LqmFZnR_zUU0BO2r0tM1&t=633087263926406250" alt="" /> " ); // 替换父节点的前的图片,把展开的图片换成空白图片
}
else
$(WebForm_GetParentByTagName(node, " table " )).remove(); // 有兄弟节点,只删除节点本身的table
}
else
alert( " 请先删除子节点 " ); // 有子节点的话不能直接删除
}
var selected = document.getElementById($( " #TreeView1_SelectedNode " ).val()); // 取得选择的节点
if (selected != null )
{
// 调用jquery的ajax方法删除节点
$.ajax( {
type: " get " ,
dataType: " text " ,
url: " treeview.aspx " ,
data: " id= " + $( " #selectedvalue " ).val(),
success: function (msg) {
if (msg == " 0 " ) // 删除成功
DelNode(selected); // 删除页面上相应的节点
else
alert(msg);
}
} );
}
else
alert( " 请先选择节点 " );
} );
function DelNode(node)
{
var subdiv = " # " + node.id.replace( " t " , " n " ) + " Nodes " ; // 节点的子节点所在div的id
if ($(subdiv).html() == null ) // 没有子节点
{
if ($(WebForm_GetParentByTagName(node, " div " )).find( " table " ).length == 1 ) // 这个用来判断是否有兄弟节点
{
// 如果只有一个节点,没有其他兄弟节点的话,就需要把这个节点所在的div一起删掉
var parentdiv = WebForm_GetParentByTagName(node, " div " )
$(parentdiv).remove();
$( " # " + parentdiv.id.replace( " t " , " n " ).replace( " Nodes " , "" )).parent().html( " <img src="/jsonTest/WebResource.axd?d=lBLgNV6VfPf2WYaPivyJeox2LqmFZnR_zUU0BO2r0tM1&t=633087263926406250" alt="" /> " ); // 替换父节点的前的图片,把展开的图片换成空白图片
}
else
$(WebForm_GetParentByTagName(node, " table " )).remove(); // 有兄弟节点,只删除节点本身的table
}
else
alert( " 请先删除子节点 " ); // 有子节点的话不能直接删除
}
其中delNode 是一个button的id,WebForm_GetParentByTagName() 函数是treeview自带的 ,可以看我以前的文章 asp.net 2.0 中 TreeView 控件中的 checkbox 客户端操作 。
以上就是主要的部分,有兴趣的朋友可以一起讨论一下。用 ajax 添加节点的方法正在研究中,下次再发。