您所在的位置: 程序员家园 -> 家园博客 ->
 
在哪里摔倒
就在哪里自己爬起来

用户登录

查  找

最新评论

最新留言

常用网站

网易邮箱 GMAIL  

百度搜索 MSDN

霏凡软件 BT精品

影视帝国 射 手 网

电驴下载 全 库 网

友情连接

茄菲的窝 冰冰博客

枫叶飘零 玫  瑰

ACEN 云 豹 子

统  计



[asp.net 2.0]TreeView读取数据库里的数据
狼子 发表于 2007-3-24 22:49:00 阅读全文 | 回复(4) | 引用通告 | 编辑

今天晚上用了两种方法,两种方法都是一次读取完数据的,测试使用的表结果是这样的:

deptid int、dna varchar(100)、parentid int、parentPath varchar(300)

分别记录自增字段的值、描述、父级编号、父级的路径(根节点的路径是“,0,”,每个路径都以“,”分隔,以“,”结尾)

第一种方法是使用js形成tree,是以前用asp的时候使用的方法,我就是把asp语句转成了C#来写

这种方法的源码是这个:UploadFiles/2007-3/324998101.rar

调用很简单:

<uc1:nnllTreeView ID="NnllTreeView1" runat="server" IDField="deptid" NeedCheckBox="false"
            NeedRadioBox="true" ParentField="parentid" TextField="dna" JSUrl="../myuo" ImgPath="../images/TreeImages/" TreeSelectCommand="select deptid,parentid,dna from T_sys_dept order by orders" />

这个方法的好处真的是无限级的树的,因为在这里我们不需要用到父级所有路径,有父级的编号就可以了

还有一个好处是容易用,因为要设置的东西很少,没有TreeView的属性这么多,一堆的东西,如果我不喜欢那些图片,我把UploadFiles/2007-3/324537444.rar里的所有图片替换,就可以换一堆图片了

这个方法的坏处是每次提交了数据回服务器,都要执行一次js里面初始化树的函数,就是我设置了!IsPostBack可以做到不会每次读取数据,就是还是每次都重新初始化整个树,因为这里的js分两个,一个是读取数据库数据,写一个脚本,另一个是执行脚本里的函数,初始化树

我试着在js里设置一个全局开关变量,当树已经第一次初始化了,就不要再重新初始化,结果是当我点了一个服务器端的Button时,整个页面变成空白了,因为返回服务器的时候,是整个页面返回的,运行过的那个读数据的js,被.net重新写回,就是没有重新调用

这个还要再想办法

第二个方法是用TreeView控件,asp.net 2.0里有这个控件,我一开始想啊想,老想着不要碰递归,所以搞了好久,后来L叔叔告诉我有FindNode方法,就变成好简单的东西了

主要是用了三个方法:

tv.Nodes.Add(new TreeNode(textValue, idValue));  //加一个节点

tn.ChildNodes.Add(new TreeNode(textValue, idValue));  //加一个子节点

tn = tv.FindNode(pathValue);  查找父级路径是pathValue的节点

我写成一个方法了:

public bool setTreeViewNode(TreeView tv, string idField, string textField, string pathField, string queryString)
    {
        bool ok = false;
        string idValue, textValue, pathValue;
        //获取连接字符串
        string connectionString = ConfigurationManager.ConnectionStrings["TTOAConnectionString"].ConnectionString;
        //创建并设置SqlConnection
        SqlConnection dbConnection = new SqlConnection(connectionString);
        try
        {
            //取数据
            dbConnection.Open();
            SqlCommand MyCommand = new SqlCommand(queryString, dbConnection);
            SqlDataReader dr = MyCommand.ExecuteReader();
            TreeNode tn = new TreeNode();

            //循环写数据
            while (dr.Read())
            {
                idValue = dr[idField].ToString();
                textValue = dr[textField].ToString();
                pathValue = dr[pathField].ToString();

                //把根节点的路径
                pathValue = pathValue.Replace(",0,", "");

                //Response.Write("<br>" + idValue.ToString() + ":" + pathValue);

                if (pathValue.Length == 0)
                {
                    tv.Nodes.Add(new TreeNode(textValue, idValue));
                }
                else
                {
                    //去掉最后的,
                    pathValue = pathValue.Remove(pathValue.Length - 1);
                    tn = tv.FindNode(pathValue);
                    if (tn != null)
                    {
                        tn.ChildNodes.Add(new TreeNode(textValue, idValue));
                    }
                }
            }
            ok = true;
        }
        catch (Exception)// e)
        {
            //Response.Write(e.Message + "<br>" + e.Source + "<br>" + e.TargetSite.Name);
            ok = false;
        }
        finally
        {
            dbConnection.Close();
        }
        return ok;
    }

这个方法的好处是他是asp.net 2.0自带的控件,所以他自己解决了回发的问题

坏处就是这种方法要使用父级的所有路径,所以不是无限的树,他的级数是被父级路径parentPath varchar(300)控制的,我这里设置了varchar(300),如果很深的树,路径的字符串超过了300,那这里就取不出了

想了一下,如果是不使用parentPath,那就不是不使用FindNode方法,就要用递归了,对不对?如果我不想用递归,我就要用一个DataTable,把每一个记录的parentid和deptid还有生成的节点的索引记录下来,然后呢,每生成一个TreeNode,我就要把这个节点的索引写入那个DataTable里,每准备生成一个TreeNode,我就要先在那个DataTable里检索他的父级对应的索引,我知道我可以对DataTable和生成树的dbCommand使用一样的字段排序,这样可以记录下当前生成到第几行,可以在回填索引值的时候不循环,就是在查找索引值的时候呢?怎么才可以做到不循环DataTable呢?

是使用递归快,还是使用循环DataTable取父级的索引快?在pb里面,我们是使用递归的,要在内存里多记录一个DataTable,资源也占用更多吧?

我现在还缺的是想要设置TreeView的文字不可点击,TreeView的文字默认是连接来的,想设置每个节点前面都有CheckBox允许多选,这个可以使用ShowCheckBoxes属性,想设置每个节点前面都有RadioBox允许单选,这个还没找到方法,嗯,想过可以利用js控制CheckBox,就是还想试一下别的方法

还有就是这里要有一个属性,PathSeparator,他是记录父级路径的分隔字符的,默认是“\”,我对应自己的数据,改成“,”了

睡觉,先记下这些东东,我要睡觉了

Re:[asp.net 2.0]TreeView读取数据库里的数据
mountain315发表评论于2007-3-25 13:09:00 个人主页 | 引用 | 返回 | 删除 | 回复

记下这段刚刚写好的js,可以修改底色,形成点击一个input,就把包含这个input在内的td整个底色换成灰

就是我现在不知道怎么把这个js加到每一个checkbox里,我可以用TreeView1.CheckedNodes访问已经通过checkbox选择的项,就是没有办法取到每一个checkbox

<html>
 <head>
  <title>test</title>
 </head>
 <body>
  <script language="JavaScript">
   function checkColor(obj)
   {
    obj=obj.parentElement;
    if(obj.style.backgroundColor=="Gainsboro")
    {
     obj.style.backgroundColor="White";
    }
    else
    {
     obj.style.backgroundColor="Gainsboro";
    }
   }
  </script>
  <base target="_blank" onclick="JavaScript:checkColor()">
  <table border="1" width="500" align="center">
   <tr>
    <td id="td1">
     <input type="checkbox" name="c1" value="1" onclick="checkColor(this);">aaa
    </td>
   </tr>
   <tr>
    <td id="td2">
     <input type="checkbox" name="c2" value="1" onclick="checkColor(this);">bbb
    </td>
   </tr>
   <tr>
    <td id="td3">
     <input type="checkbox" name="c3" value="1" onclick="checkColor(this);">ccc
    </td>
   </tr>
  </table>
 </body>
</html>

Re:[asp.net 2.0]TreeView读取数据库里的数据
mountain315发表评论于2007-3-25 13:41:00 个人主页 | 引用 | 返回 | 删除 | 回复

使用event.srcElement就可以不用给每一个checkbox添加客户端脚本了,就像以前做的要点击了广告才可以下载东西一样

<script type="text/javascript">
   function checkColor()
   {
    var obj = window.event.srcElement;
    if(obj.tagName=="INPUT" && obj.type=="checkbox")
    {
     var cb=obj;
     var td=cb.parentElement;
     if(cb.checked)
     {
      td.style.backgroundColor="Gainsboro";
      td.style.color="blue";
     }
     else
     {
      td.style.backgroundColor="White";
      td.style.color="black";
     }
    }
   }
  </script>

设置<asp:TreeView onclick="checkColor();">就可以生成<div onclick="checkColor();">

现在还差的问题是,TreeView的文字,怎么去掉连接?因为点击文字不可以同时选择那个checkbox,我不想要这个文字连接

Re:[asp.net 2.0]TreeView读取数据库里的数据
mountain315发表评论于2007-3-25 20:54:00 个人主页 | 引用 | 返回 | 删除 | 回复

解决点击文字和checkbox不同步的问题:

protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
    {
        if (showCheckbox)
        {
            TreeView1.SelectedNode.Checked = true;
        }
    }

Re:[asp.net 2.0]TreeView读取数据库里的数据
mountain315发表评论于2007-9-1 18:04:00 个人主页 | 引用 | 返回 | 删除 | 回复

节点的SelectAction属性有四个值:

TreeNodeSelectAction.Select:点击节点就会选中这个节点

TreeNodeSelectAction.Expand:点击节点会展开这个节点

TreeNodeSelectAction.SelectExpand:点击节点会选中这个节点,还会展开这个节点的

TreeNodeSelectAction.None:没有操作,所以节点会就以文本的方式显示,不会显示成连接,点击时不会执行任何js

发表评论:

    昵称:
    密码:
    主页:
    标题:
Powered by Oblog.