浅析TreeView控件的操作(上)
treeView控件是网页中很常用的一个导航控件,所以,额。。。。反正就是很常用就对了啦,正好在公司这边,军哥交给我的第一个功能模块就是做对TreeView控件的操作,也就是增删改
以上为背景,背景介绍完了,进入正题:
【1】动态加载节点的方法:
(1)一种很直白并且很容易想到的方法--------递归
原理:在数据表中查出所有数据,然后递归遍历数据中的节点,添加节点上树中。。。。
话不多说,直接上代码:
#region 绑定TreeView /// <summary> /// 绑定TreeView(利用TreeNode) /// </summary> /// <param name="p_Node">TreeNode(TreeView的一个节点)</param> /// <param name="pid_val">父id的值</param> /// <param name="id">数据库 id 字段名</param> /// <param name="pid">数据库 父id 字段名</param> /// <param name="text">数据库 文本 字段值</param> protected void Bind_Tv(DataTable dt, TreeNode p_Node, string pid_val, string id, string pid, string text) { DataView dv = new DataView(dt);//将DataTable存到DataView中,以便于筛选数据 TreeNode tn;//建立TreeView的节点(TreeNode),以便将取出的数据添加到节点中 //以下为三元运算符,如果父id为空,则为构建“父id字段 is null”的查询条件,否则构建“父id字段=父id字段值”的查询条件 string filter = string.IsNullOrEmpty(pid_val) ? pid + " is null" : string.Format(pid + "={0}", pid_val); dv.RowFilter = filter;//利用DataView将数据进行筛选,选出相同 父id值 的数据 foreach (DataRowView row in dv) { tn = new TreeNode();//建立一个新节点(学名叫:一个实例) if (p_Node == null)//如果为根节点 { tn.Value = row[id].ToString();//节点的Value值,一般为数据库的id值 tn.Text = row[text].ToString();//节点的Text,节点的文本显示 TreeView1.Nodes.Add(tn);//将该节点加入到TreeView中 Bind_Tv(dt, tn, tn.Value, id, pid, text);//递归(反复调用这个方法,直到把数据取完为止) } else//如果不是根节点 { tn.Value = row[id].ToString();//节点Value值 tn.Text = row[text].ToString();//节点Text值 p_Node.ChildNodes.Add(tn);//该节点加入到上级节点中 Bind_Tv(dt, tn, tn.Value, id, pid, text);//递归 } } } #endregion
这个已经装好的一个方法了,可以直接拿去用,这个方法只是适用于所有节点都加起来不要超过50个就好了,一多的话就会加载半天都出不来的;所以,对于数据量庞大的,但是加载又比较快一点的,就下面的方法好点了
原理:先加载最顶的根节点,然后判断该节点下面是否有子节点,有就设置节点前面的加号,然后在TreeView1_TreeNodePopulate事件中记载选中节点的下一级节点,再判断节点是否有子节点,设置节点前面的加号事件。。。。。。。。一尺类推
额。。。这次简单点,不用递归了,直接循环就好了
话不多说,上代码:
PS:1、获取数据库中的数据我是用到我自己封装的Sqlhelper类,下面有下载链接
2、我数据库中的最顶层的父节点的值是0
最先的是在页面的Load事件中加载树的最顶层节点,需要检验节点是否存在子节点
然后在TreeView1_TreeNodePopulate中加载树需要展开节点的最顶层子节点
代码:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { TreeView1.Nodes.Clear(); string sql = "select * from tree where preID=0"; dt=sh.ExecuteQuery (sql,CommandType.Text ); //Bind_Tv(dt, TreeView1.Nodes,"0", "ID", "preID", "Name"); //Bind(dt,(TreeNode )null, "0", "preID", "ID", "Name"); //接在树状图的根节点 Bind_Root(dt); } } private void Bind_Root(DataTable dt) { TreeNode tn; for (int i = 0; i < dt.Rows.Count; i++) { tn = new TreeNode(); tn.Value = dt.Rows[i][0].ToString(); tn.Text =dt.Rows [i][1].ToString (); //判断是否有子节点 if (Check_Child(tn.Value)) { tn.PopulateOnDemand = true; tn.Expanded = false; } TreeView1.Nodes.Add(tn); } } private bool Check_Child(string pre_Val) { string sql = "select * from tree where preID='" + pre_Val + "'"; DataTable dt = sh.ExecuteQuery(sql, CommandType.Text); if (dt.Rows.Count > 0) { return true; } return false; } protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e) { Bind_Child (e.Node,e.Node.Value.ToString ()); } /// <summary> /// 绑定节点的子节点 /// </summary> /// <param name="treeNode"></param> /// <param name="p"></param> private void Bind_Child(TreeNode treeNode, string pre_Val) { TreeNode tn; string sql = "select * from Tree where preID='" + pre_Val + "'"; DataTable dt = sh.ExecuteQuery(sql, CommandType.Text); for (int i = 0; i < dt.Rows.Count; i++) { tn =new TreeNode(); tn.Value =dt.Rows[i][0].ToString (); tn.Text= dt.Rows[i][1].ToString(); //检验是否有子节点 if(Check_Child (tn.Value)) { tn.PopulateOnDemand = true; tn.Expanded = false; } treeNode.ChildNodes .Add(tn); } }
相对比之下,第一种方法比较直观,直接可以看到全部的节点,方便查询,第二种加载比较快,适合大量数据的加载,至于需要哪种,视具体情况而定
【2】插入节点,插入节点又分为两种,一种是同级的节点,一种是子级的节点
插入同级节点:(这段不给代码了,提供思路)
插入同级节点时候,需要获取的是父节点的父节点的Value的值,显示的字段。。。。插入数据库,然后你会有两种选择,一种将树的所有节点去掉,再绑定Load一遍;另外一种就是实例化一个节点,设置节点的Text,Value属性后,将其添加到选中的节点的父节点的子节点集中
部分代码:
//添加同级节点因为就是在选中节点的父节点的子节点中添加子节点 //同样不需要重新绑定重新刷新一遍 TreeNode tn = new TreeNode(); tn.Text = Name.Text; tn.Value = Remark.Text; TreeView1.SelectedNode.Parent.ChildNodes.Add(tn);
第二种方法的好处就是你可以立即看到你做得动作。。。。。
插入子级节点的话,需要获取选中节点的value值,还有就是显示的值。。。和前面一样,插入数据库,然后你会有两种选择,一种将树的所有节点去掉,再绑定Load一遍;还是有两种选择,和上面差不多
部分代码:
TreeNode tn = new TreeNode(); tn.Text = Name.Text; tn.Value = Remark.Text; string sql = "insert into tree(Name,preID) values('" + Name.Text.Trim() + "','" + ID.Text.Trim() + "')"; sh.ExecuteNonQuery(sql, CommandType.Text); TreeView1.SelectedNode.ChildNodes.Add(tn); TreeView1.SelectedNode.Expand();
要提醒的是;插入子级节点的话,是需要添加最后一句代码的,因为默认是不展开节点的,所以你加进去没有展开也是看不到的
额。。。。。没了,插入就是这样了。。。。。
【3】修改
这,这,这。。。。不用说了吧如果不懂的话,看一下插入就是了啦,还是不懂?!
就是将选中的节点的显示文本替换一下嘛,其他的没有显示,就直接插入数据库就好了啦
代码:
没有代码了啦,这个,不知道和谁私奔去了~~~
【4】删除节点
很晚了,不写了,欲知后事如何,请拨10086转0
PS:数据库助手类在这里可以下载
http://download.csdn.net/detail/kc675904085/3831231