树TreeView控件与DataTable交互添加节点(最高效的方法)

简介: 方法一: View Code 本文转载:http://dengzebo.blog.163.com/blog/static/18867406201032141742168/#region "读取树结点从Datatable"        ///         /// 读取树结点从Data...

方法一:

View Code
本文转载:http: // dengzebo.blog.163.com/blog/static/18867406201032141742168/


#region "读取树结点从Datatable"

         ///   <summary>

        
///  读取树结点从Datatable"

        
///   </summary>

        
///   <param name="TreeView1"> 在填充的TreeView控件 </param>

        
///   <param name="DT"> 数据源DataTable </param>

        
///   <param name="IsAppendNode"> 是在现有TreeView控件上添加结点,还是清空再添加 </param>

        
///   <param name="ParentNumberColumnIndex"> 在DataTable中,代表父节点编号的列索引 </param>

        
///   <param name="NumberColumnIndex"> 在DataTable中,代表当前节点编号的列索引 </param>

        
///   <param name="NameColumnIndex"> 在DataTable中,代表当前节点名称的列索引 </param>

        
///   <returns> True/False </returns>

         public  bool ReadNodesFromDataTable(TreeView TreeView1, DataTable DT,  bool IsAppendNode,  int ParentNumberColumnIndex,  int NumberColumnIndex,  int NameColumnIndex)

        {

             try

            {

                 if (IsAppendNode ==  false)

                {

                    TreeView1.Nodes.Clear();

                }

                 if (DT !=  null && DT.Rows.Count >  0)

                {

                    DataRow[] DR =  null;

                    DR = DT.Select(DT.Columns[ParentNumberColumnIndex].ColumnName +  " ='' or  " + DT.Columns[ParentNumberColumnIndex].ColumnName +  " ='0' or  " + DT.Columns[ParentNumberColumnIndex].ColumnName +  "  is null "); // 先将顶级的查出来
                     for ( int I =  0; I <= DR.Length -  1; I++) // 先将顶级的加入到TreeView中
                    {

                        TreeNode TNode =  new TreeNode(DR[I][DT.Columns[NameColumnIndex].ColumnName].ToString());

                        TNode.Tag = DR[I][DT.Columns[NumberColumnIndex].ColumnName].ToString();

                        TNode.Name = DR[I][DT.Columns[NameColumnIndex].ColumnName].ToString();

                        TreeView1.Nodes.Add(TNode);

                    }

                     for ( int I =  0; I <= TreeView1.Nodes.Count -  1; I++) // 再递归遍历结点
                    {

                        ForTreeNodeFormDT(TreeView1.Nodes[I], DT, ParentNumberColumnIndex, NumberColumnIndex, NameColumnIndex);

                    }

                }

                 return  false;

            }

             catch

            {

                 return  true;

            }

        }

 

         ///   <summary>

        
///  从DT中递归遍历出结点
        
///   </summary>

        
///   <param name="TempNode"> 传入的顶级结点 </param>

        
///   <param name="DT"> 保存TreeView结构的DataTable </param>

        
///   <param name="ParentNumberColumnIndex"> 在DataTable中,代表父节点编号的列索引 </param>

        
///   <param name="NumberColumnIndex"> 在DataTable中,代表当前节点编号的列索引 </param>

        
///   <param name="NameColumnIndex"> 在DataTable中,代表当前节点名称的列索引 </param>

         private  void ForTreeNodeFormDT(TreeNode TempNode, DataTable DT,  int ParentNumberColumnIndex,  int NumberColumnIndex,  int NameColumnIndex)

        {

             string TTag =  null;

            TTag = TempNode.Tag.ToString();

            DataRow[] DR =  null;

            DR = DT.Select(DT.Columns[ParentNumberColumnIndex].ColumnName +  " =' " + TTag +  " ' ");

 

             for ( int I =  0; I <= DR.Length -  1; I++)

            {

                TreeNode TNode =  new TreeNode(DR[I][DT.Columns[NameColumnIndex].ColumnName].ToString());

                TNode.Tag = DR[I][DT.Columns[NumberColumnIndex].ColumnName].ToString();

                TNode.Name = DR[I][DT.Columns[NameColumnIndex].ColumnName].ToString();

                TempNode.Nodes.Add(TNode);

            }

 

             foreach (TreeNode aNode  in TempNode.Nodes)

            {

                ForTreeNodeFormDT(aNode, DT, ParentNumberColumnIndex, NumberColumnIndex, NameColumnIndex);

            }

        }

         #endregion

 

 

方法二:

 

做分类 经常会用到无限级别的分类  先介绍一下数据库的表结构

tid  类别编号

tname 类别名称

pid 父类编号

测试数据就不写了,大家可以自己插入一下试试

查询制定类别的 所有的子类   sql 的 代码

with as 递归查询
复制代码
alter proc  proc_chaxun
(@tid int )
as
begin  

    
    with tt  as 
    (
        
        select tid,tname,pid from dbo.t_goodsType where tid=@tid
        union all
        select t.tid,t.tname,t.pid from dbo.t_goodsType  t inner join tt
        on t.pid=tt.tid
    )
    select * from tt
end 
复制代码

查询之后获取记录集   绑定到前台的 TreeView 上面

递归进行添加
复制代码
 /// <summary>
            /// 给Tree 绑定数据 递归添加子节点
            /// </summary>
            /// <param name="dv">数据视图</param>
            /// <param name="tnOld">添加数据的节点</param>
            public void TreeDataBind(DataView dv,TreeNode tnOld)
            {
                TreeNode tnNew;    //创建一个新的节点
                foreach (DataRowView drv in dv)
                {
                    //为新的借点设置属性 
                    tnNew = tnOld.Nodes.Add(drv["tname"].ToString());
                    tnNew.Tag = drv["tid"];
                    //过滤数据视图 父类id = 上一级的tid
                    dv.RowFilter = "pid=" + drv["tid"].ToString();
                    //自己调用自己 
                    TreeDataBind(dv, tnNew);
                }
            }
          
复制代码

调用的方法很简单

调用
DataTable dtRet = (DataTable)dh.ExecProcRetObj(ep);
DataView dv = new DataView(dtRet);
 dv.RowFilter = "pid=0";
TreeDataBind(dv, this.treeView1.Nodes.Add("商品类别"));

效果

 

[知识分享] LINQ TO SQL 实现无限递归查询

本文转载:http://blog.csdn.net/q107770540/article/details/7708418

List<DetptInfo> lstDept = new List<DetptInfo> 
{
new DetptInfo {ID=1,DeptName="公司",ParentID=0},
new DetptInfo {ID=10,DeptName="软件中心",ParentID=1},
new DetptInfo {ID=11,DeptName="综合办公室",ParentID=1},
new DetptInfo {ID=100,DeptName="人力资源部",ParentID=11},
new DetptInfo {ID=101,DeptName="行政部",ParentID=11},
};



public static List<DetptInfo> GetSonID(List<DetptInfo> lstDept, int p_id)
{
var query = from c in lstDept
where c.ParentID == p_id
select c;

return query.Concat(query.SelectMany(t => GetSonID(lstDept, t.ID))).ToList();
}



--调用:

var query = GetSonID(lstDept, 0);
Console.WriteLine("Id\tName\tParent");

query.ToList().ForEach(q => Console.WriteLine("{0}\t{1}\t{2}", q.ID, q.DeptName, q.ParentID));

  

目录
相关文章
|
域名解析 弹性计算 Linux
阿里云购买云服务器、注册域名、备案及绑定图文教程参考
本文为大家介绍了2024年购买阿里云服务器和注册域名,绑定以及备案的教程,适合需要在阿里云购买云服务器、注册域名并备案的用户参考,新手用户可通过此文您了解在从购买云服务器到完成备案的流程。
阿里云购买云服务器、注册域名、备案及绑定图文教程参考
|
tengine 负载均衡 应用服务中间件
Nginx+Keepalived高可用集群部署详细文档
Nginx+Keepalived高可用集群部署详细文档
752 0
|
安全 Linux Shell
SSH 命令完整实用指南 | Linux SSH 服务
【8月更文挑战第20天】
1588 0
|
安全
qt.qpa.xcb: could not connect to display 问题解决
【5月更文挑战第16天】qt.qpa.xcb: could not connect to display qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. 问题解决
7267 1
|
Linux Shell 网络安全
centos 查看哪些服务是自启动的
在CentOS中,可以使用`systemctl`命令来查看哪些服务是自启动的。具体的步骤如下: 1. 打开终端或者SSH连接到CentOS服务器上。 2. 输入以下命令来列出所有自启动的服务: ```bash systemctl list-unit-files --type=service | grep enabled ``` 这将显示所有已启用的服务。 另外,你也可以使用以下命令来查看所有已启用和已禁用的服务: ```bash systemctl list-unit-files --type=service ``` 已禁用的服务将以"disabled"的形式显示。
1121 0
|
JavaScript
树形组件(可动态添加属性、无限嵌套)及递归展示tree数据
树形组件(可动态添加属性、无限嵌套)及递归展示tree数据
树形组件(可动态添加属性、无限嵌套)及递归展示tree数据
|
存储 Prometheus 监控
使用 Docker 部署 Prometheus + Grafana 监控平台
Prometheus(普罗米修斯R)是一套开源的监控&报警&时间序列数据库的组合,由SoundCloud公司开发。
19658 4
使用 Docker 部署 Prometheus + Grafana 监控平台
|
SQL 存储 程序员
C#连接数据库之Connection、Command、DataReader用法总结
C#连接数据库之Connection、Command、DataReader用法总结
490 0
C#连接数据库之Connection、Command、DataReader用法总结
|
应用服务中间件
修改Keepalived配置文件位置以及重定向Keepalived日志的输出路径
上一篇博文主要讲述了如何使用Keepalived实现tomcat服务器的双机热备。这篇博文是对上一篇博文的扩展,主要讲述如何修改Keepalived的默认配置文件的路径以及重定向Keepalived日志的输出路径。
3809 0
|
2天前
|
弹性计算 运维 搜索推荐
三翼鸟携手阿里云ECS g9i:智慧家庭场景的效能革命与未来生活新范式
三翼鸟是海尔智家旗下全球首个智慧家庭场景品牌,致力于提供覆盖衣、食、住、娱的一站式全场景解决方案。截至2025年,服务近1亿家庭,连接设备超5000万台。面对高并发、低延迟与稳定性挑战,全面升级为阿里云ECS g9i实例,实现连接能力提升40%、故障率下降90%、响应速度提升至120ms以内,成本降低20%,推动智慧家庭体验全面跃迁。