浅析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







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值