首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 构建TreeView无限制级的树形????? [已结贴,结贴人:Jason009]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 13:57:28 楼主
    如何根据查询出来的数据构建树形,而且是无限制级的?
    比如有一个结果集为下面的数据:
    模块组编码是分级编码的概念,4位一级,最多5级,按左匹配原则分级,举例如下:
    IDModule IdCode                IdName
    1        0001                  系统管理
    2        00010001              帐套管理
    3        00010002              安全管理
    4        000100020001          部门管理
    5        000100020002          角色管理
    6        000100020003          A管理
    7        0001000200030001      A001
    8        0001000200030002      A002
    9        0001000200030003      A003
    10        0001000200030004      A004
    11        00010002000300040001  A004001
    12        00010002000300040002  A004002
    -------------------------------------------------------
    其中操作表如下,以IDModule为关联:

    IDModule  OprCode  OprName
    4        Delete  删除
    4        Enter    进入
    4        Modify  修改
    4        New    新增
    4        Print    打印
    =======================================
    这样的,不知道如何能更好的构建树形结构,请各位高手指教,谢谢!!!
    该帖包含附件:http://dl2.csdn.net/down4/20080428/28135419435.JPG
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 14:01:551楼 得分:0
    就像下面图形一样:

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • avrilxu
    • 等级:
    发表于:2008-04-28 14:02:482楼 得分:20
    http://www.lokcore.com/avrilxu/article.asp?id=3
    treeview的递归调用,我对树颇有研究,喜欢研究的,去我博客留言大家交流吧,我做了好几个treeview的项目,应该有些心得吧,期待抛砖引玉
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • avrilxu
    • 等级:
    发表于:2008-04-28 14:03:413楼 得分:0
    我以前做过一个权限树,貌似跟楼主的一样,不过我的比楼主的麻烦多了,因为我的树上要反应出业务权限和数据权限
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 14:10:344楼 得分:0
    哦,有没有源码之类,发来看看。
    因为我自己也做了,只是感觉不是很好,才需要大家来看看。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 15:00:245楼 得分:0
    权限系统?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 15:02:446楼 得分:20
    思路参考: http://www.ithome-cn.net/technology/mis/mis80.htm
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 15:06:217楼 得分:0
    先把第一级节点构造出来,然后循环看一级节点是否有儿子,有儿子就添加,递归调用直到没有为止
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 15:16:218楼 得分:0
    嗯.先读根节点.之后,判断子节点数量是不为0.不为0再次把这个节点给递归函数,遍历子节点.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 15:20:459楼 得分:5
    我基本不用treeView,都是自己写代码拼出树形(用div,table,gif,label,checkbox....),好处是灵活,想怎么显示都可以。
    当然基本算法是递归了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 16:05:5410楼 得分:0
    引用 9 楼 apollolb2005 的回复:
    我基本不用treeView,都是自己写代码拼出树形(用div,table,gif,label,checkbox....),好处是灵活,想怎么显示都可以。
    当然基本算法是递归了


    强!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 16:18:4111楼 得分:0
    都是强人,我只是想要一个最佳的解决方案而已。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 16:24:0112楼 得分:5
    用层级码做树形是不能无限级的,受层级码字段长度的限制,好处是查询汇总快。

    要用parent才算的上是无限级。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • yagebu1983
    • 等级:
    发表于:2008-04-28 16:33:2413楼 得分:0
    看了高手的回复,
    学到了很多东西!!
    谢谢楼主!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 16:40:1614楼 得分:0
    学习了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 18:00:2915楼 得分:0
    我的代码如下,但,感觉还是不是很好,有什么更好的方法吗??
            #region 创建模块组树
            private void AddTreeViewData()
            {
                RoleTreeNode firstTreeNode = null;
                int moduleID = -1;
                string filterStr = null;
                string moduleGroupName = null;
                string moduleGroupCode = "";
                int moduleGroupCount = 0;
                int length = 4;

                this.dtModuleList = this.dsModuleOperateList.Tables["AdmModGroup"];
               
                length = moduleGroupCode.Trim().Length + 4;

                filterStr = "LEN(ModuleGroupCode) =  " + length.ToString();
                DataView dvModuleGroup = new DataView(this.dtModuleList, filterStr, "ModuleGroupCode", DataViewRowState.CurrentRows);

                moduleGroupCount = dvModuleGroup.Count;

                if (moduleGroupCount <= 0) return;

                for (int i = 0; i < moduleGroupCount; i++)
                {
                    //增加第一节点(模块组AdmModuleGroup中modulegroupcode编码长度等于8的级别)
                    firstTreeNode = new RoleTreeNode();
                    moduleGroupName = dvModuleGroup[i]["ModuleGroupName"].ToString();
                    moduleGroupCode = dvModuleGroup[i]["ModuleGroupCode"].ToString();
                    moduleID = Convert.IsDBNull(dvModuleGroup[i]["ModuleID"]) ? -1 : int.Parse(dvModuleGroup[i]["ModuleID"].ToString());

                    firstTreeNode.ModuleGroupCode = moduleGroupCode;
                    firstTreeNode.RoleCode = this.roleCode;
                    firstTreeNode.AccountID = this.currentAccountID;
                    firstTreeNode.NodeType = 0;
                    firstTreeNode.ModuleID = moduleID;
                    firstTreeNode.Text = moduleGroupName;
                    firstTreeNode.ImageIndex = 0;
                    firstTreeNode.SelectedImageIndex = 1;

                    this.treeViewEx1.Nodes.Add(firstTreeNode);

                    //增加模块组AdmModuleGroup中modulegroupcode编码长度大于等于12的所有子级
                    AddSecondTreeNode(firstTreeNode, moduleID, moduleGroupCode);
                    //增加功能节点
                    AddTreeOpr(firstTreeNode, moduleID, moduleGroupCode);
                }
            }

            private void AddSecondTreeNode(RoleTreeNode treeNode, int moduleID, string moduleGroupCode)
            {
                //增加模块组AdmModuleGroup中modulegroupcode编码长度大于等于12的所有子级
                int length = 4;
                string filterStr = "";
                string nextModuleGroupName = "";
                string nextModuleGroupCode = "";
                RoleTreeNode secondTreeNode = null;

                this.dtModuleList = this.dsModuleOperateList.Tables["AdmModGroup"];

                length = moduleGroupCode.Trim().Length + 4;
                filterStr = "LEN(ModuleGroupCode) =  " + length.ToString() + " and ModuleGroupCode like '" + moduleGroupCode + "%'";
                DataView dv = new DataView(this.dtModuleList, filterStr, "ModuleGroupCode", DataViewRowState.CurrentRows);

                for (int j = 0; j < dv.Count; j++)
                {
                    secondTreeNode = new RoleTreeNode();
                    nextModuleGroupName = dv[j]["ModuleGroupName"].ToString();
                    nextModuleGroupCode = dv[j]["ModuleGroupCode"].ToString();
                    moduleID = Convert.IsDBNull(dv[j]["ModuleID"]) ? -1 : int.Parse(dv[j]["ModuleID"].ToString());
                    secondTreeNode.ModuleID = moduleID;
                    secondTreeNode.RoleCode = this.roleCode;
                    secondTreeNode.AccountID = this.currentAccountID;
                    secondTreeNode.ModuleGroupCode = nextModuleGroupCode;
                    secondTreeNode.NodeType = nextModuleGroupCode.Trim().Length / 4 - 1;
                    secondTreeNode.Text = nextModuleGroupName;
                    secondTreeNode.ImageIndex = 0;
                    secondTreeNode.SelectedImageIndex = 1;
                    treeNode.Nodes.Add(secondTreeNode);

                    if (moduleID < 0)
                        AddSecondTreeNode(secondTreeNode, moduleID, nextModuleGroupCode);//增加模块组AdmModuleGroup中modulegroupcode编码长度大于等于12的所有子级
                    else
                        AddTreeOpr(secondTreeNode, moduleID, nextModuleGroupCode);//增加功能节点
                }
            }

            private void AddTreeOpr(RoleTreeNode treeNode, int moduleID, string moduleGroupCode)
            {
                //增加各模块操作节点
                this.dtOprList = this.dsModuleOperateList.Tables["AdmModOpr"];
                string filterStr = "ModuleID = " + moduleID.ToString();
                DataView dvOpr = new DataView(this.dtOprList, filterStr, "OprCode", DataViewRowState.CurrentRows);

                if (dvOpr.Count <= 0) return;

                RoleTreeNode threeTreeNode = null;

                for (int k = 0; k < dvOpr.Count; k++)
                {
                    threeTreeNode = new RoleTreeNode();
                    threeTreeNode.OprCode = dvOpr[k]["OprCode"].ToString();
                    threeTreeNode.ModuleID = Convert.IsDBNull(dvOpr[k]["ModuleID"]) ? -1 : int.Parse(dvOpr[k]["ModuleID"].ToString());
                    threeTreeNode.ModuleGroupCode = moduleGroupCode;
                    threeTreeNode.RoleCode = this.roleCode;
                    threeTreeNode.AccountID = this.currentAccountID;
                    threeTreeNode.NodeType = 3;
                    threeTreeNode.Text = dvOpr[k]["OprName"].ToString();
                    threeTreeNode.ImageIndex = 0;
                    threeTreeNode.SelectedImageIndex = 1;
                    treeNode.Nodes.Add(threeTreeNode);

                    //处理已在数据表中存在的子节点
                    filterStr = "AccountID = " + this.currentAccountID +
                        "and RoleCode = '" + this.roleCode + "'" +
                        "and OprCode = '" + dvOpr[k]["OprCode"].ToString() + "'" +
                        "and ModuleID = " + dvOpr[k]["ModuleID"].ToString();
                    DataView dvChenkOpr = new DataView(this.dataSetRoleData1.ADMROLERIGHT, filterStr, "OprCode", DataViewRowState.CurrentRows);
                    if (dvChenkOpr.Count > 0)
                        threeTreeNode.Checked = true;
                }

            }
            #endregion
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 21:07:5616楼 得分:0
    建议楼主直接去Down一个TreeListView控制。 DevExpress公司的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 21:31:0517楼 得分:0
    递归吧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 21:39:4918楼 得分:0
    思路都差不离的,除了递归还是递归;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-28 22:34:4519楼 得分:0
    xue xi
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 11:22:0020楼 得分:0
    无限制就是做递归了。。。递归就是无限制循环到最后
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 13:45:3721楼 得分:0
    好象别个都有做好的了,还在自己写?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 15:35:2422楼 得分:30
    刚做完一个,VS 2003版本,自己稍作改动就好拉

    treeView1.BeginUpdate();
    treeView1.Nodes.Clear();
    treeView1.Nodes.Add(FillTreeNode());
    treeView1.EndUpdate();


    //装配树
    private TreeNode FillTreeNode()
    {
    //创建根节点
    TreeNode rootNode= new TreeNode("Content Root");
    rootNode.Tag="System";

    TreeNode parentNode=rootNode;
    TreeNode childNode;
    string key;

    DataTable dt=DAL.ExecSqlToDataTable("SELECT ParentGroupNo, GroupNo, GroupName FROM dbo.FDM_ContentGroup ORDER BY GroupNo");
    for (int i=0;i <dt.Rows.Count;i++)
    {
    key=dt.Rows[i][0].ToString();
    if (key=="System")
    {
    parentNode=new TreeNode();
    parentNode.Tag=dt.Rows[i][1].ToString();
    parentNode.Text =dt.Rows[i][2].ToString();
    rootNode.Nodes.Add(parentNode);
    }
    else
    {
    parentNode=FindTreeNode(rootNode,key);
    if (parentNode!=null)
    {
    childNode=new TreeNode();
    childNode.Tag=dt.Rows[i][1].ToString();
    childNode.Text =dt.Rows[i][2].ToString();
    parentNode.Nodes.Add (childNode);
    }
    }
    }

    rootNode.ExpandAll();
    return rootNode;
    }

    //查找节点: 如找到则返回该节点,否则返回空值
    //算法实现: xlFancy  2008.02.29
    private TreeNode  FindTreeNode(TreeNode tn, string key)
    {
    if (tn.Tag.ToString() == key) return tn;

    TreeNode node = null;
    for (int i = 0; i < tn.Nodes.Count; i++)
    {
    if (tn.Nodes[i].Tag.ToString() == key) node = tn.Nodes[i];
    if (node!=null) break;
                   
    node = FindTreeNode(tn.Nodes[i], key);
    }
    return node;
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 16:15:5523楼 得分:10
    梅花开有个开源的treeview控件,这个csdn也用的她呀,蛮好的啊,可以试试
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 16:19:2424楼 得分:0
    学习了...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-29 16:29:1425楼 得分:0
    在vs2005下面,无限制级可以不使用递归.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-30 10:13:0526楼 得分:0
    要是有这样的控件就好了,
    比如:我指定数据源--dtgroup,然后我指定最大节点级数,然后像DataGridView一样,我可以指定第一节点的相关参数(例如:帐套ID,角色编码,模块ID,操作编码,模块组编码,及节点显示的名称和Value(这里有点像ComboBox),还有一个最重要就是根据指定的数据源来过滤数据的条件---》这个过滤的数据,是形成节点的)、第二节点等数据;然后就是通过选择来确定你选择的节点的各个参数的值(以便保存在另外一张表中或其它用处)。
    -------------------------
    不知道有没有人做过相关的,是否可以形成公共的控件,有的话请共享,谢谢了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-30 19:42:2127楼 得分:0
    关注 接分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-01 14:48:3528楼 得分:0
    该回复于2008-05-11 15:10:25被版主删除
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-04 09:50:0429楼 得分:0
    顶!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-04 14:16:4830楼 得分:10


    表结构这样设计:
    bh ,mc ,parentBh
    01  01 
    02  02
    03  03
    0101  0101  01
    0102  0102  01
    010101  010101  0101

    数据如上存放,使用递归的方式加载!

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-14 10:32:5331楼 得分:0
    虽然没找到满意的答案,但是还是结贴吧。
    哎。。。。。。。。。。。。。。。
    修改 删除 举报 引用 回复