C# Web控件与数据感应之 TreeView 类

目录

[关于 TreeView](#关于 TreeView)

一些区别

准备数据源

范例运行环境

一些实用方法

获取数据进行呈现

​根据ID设置节点

获取所有结点的索引

小结


关于 TreeView

数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,本文将继续介绍与数据库提取数据并捆绑到 TreeView 类控件。在我的前期文章《C# DataSet结合FlyTreeView显示树状模型数据》,对于 FlyTreeView 已做过介绍,本文则介绍C# 实现 Microsoft.Web.UI.WebControls.TreeView 和 System.Web.UI.WebControls.TreeView 的一些实用方法。

一些区别

Microsoft.Web.UI.WebControls.TreeView 、 System.Web.UI.WebControls.TreeView 和NineRays.WebControls.FlyTreeView 在使用和呈现上大同小异,关键的区别在于 FlyTreeView不是免费的,即使使用破解版本可能也存在部分问题,这个在使用中需要注意。而Microsoft.Web.UI.WebControls.TreeView 和 System.Web.UI.WebControls.TreeView 是微软提供的内置控件,前者是 TreeView 的早期版本,现在基本以 System.Web.UI.WebControls.TreeView 为准。本文将以 Microsoft.Web.UI.WebControls.TreeView 为举例,实现上与后者没有区别。

准备数据源

我们在 MS SQL Server 创建 pub_area(区域表),其结构如下表:

| 序号 | 字段名 | 类型 | 说明 |
| 1 | acode | nvarchar(10) | 区域代码,唯一键 |
| 2 | aname | nvarchar(50) | 区域名称 |

3 parent_acode nvarchar(10) 父项所属区域代码

执行如下 创建表的 SQL 语句:

sql 复制代码
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[pub_area](
	[acode] [nvarchar](10) NOT NULL,
	[aname] [nvarchar](50) NOT NULL,
	[parent_acode] [nvarchar](10) NULL,
 CONSTRAINT [IX_pub_area] UNIQUE NONCLUSTERED 
(
	[acode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

执行如下SQL语句,创建一些数据:

sql 复制代码
insert into pub_area(acode,aname,parent_acode) values('01','天津市','')
insert into pub_area(acode,aname,parent_acode) values('0101','南开区','01')
insert into pub_area(acode,aname,parent_acode) values('010101','学府街道','0101')
insert into pub_area(acode,aname,parent_acode) values('010102','万兴街道','0101')

通过查询分析器,执行查询SQL语句,显示如下图:

最后我们将数据填充到 DataSet 即可,具体操作可参考我的文章《C# 利用IDbDataAdapter / IDataReader 实现通用数据集获取》

范例运行环境

操作系统: Windows Server 2019 DataCenter

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.0 或以上

开发工具:VS2019 C#

一些实用方法

获取数据进行呈现

simpletreeview方法主要是通过DataSet数据源进行提取呈现的TreeView控件上,方法返回 int 类型,表示成功返回当前节点的节点数,其参数设置见下表:

| 序号 | 参数名 | 类型 | 说明 |
| 1 | tv | Microsoft.Web.UI.WebControls. TreeNodeCollection | 传入的TreeView的当前结点集合对象 |
| 2 | ds | DataSet | 数据集对象,默认只取Tables[0] |
| 3 | key | string | 数据表的唯一标识字段名 |
| 4 | parentkey | string | 数据表的父结点字段名 |
| 5 | dis | string | 数据表的显示名称字段名 |
| 6 | keytype | string | 标识类型,这是我们自定的规范,比如CID(字符)、ID(数值)固定名称的处理方式,默认处理方式对key或parentKey进行字符串过滤处理 |
| 7 | initvalue | string | 是否指定一个初始值 |
| 8 | firstlevel | bool | 是否指遍历一级,如果为true,则不在进行递归 |

9 initByKey bool 初始值使用哪个关键字段,false使用父节点,true使用唯一标识,默认为false

实现代码如下:

cs 复制代码
		public int simpletreeview(Microsoft.Web.UI.WebControls.TreeNodeCollection tv,DataSet ds,string key,string parentkey,string dis,string keytype,string initvalue,bool firstlevel,bool initByKey)
		{
			int rv=0;
			DataView dv=new DataView();
			dv.Table=ds.Tables[0];

            Microsoft.Web.UI.WebControls.TreeNode tmpNd;
			if((keytype=="uniqueidentifier")&&(initvalue==""))
			{
				dv.RowFilter=" "+(initByKey==false?parentkey:key)+" is null ";
			}
			else
			{
				dv.RowFilter="isnull("+(initByKey==false?parentkey:key)+",'')='"+initvalue+"'";
			}
			rv=dv.Count;
			foreach(DataRowView drv in dv)
			{
                tmpNd = new Microsoft.Web.UI.WebControls.TreeNode();
				tmpNd.ID=drv[key].ToString();
				tmpNd.Text=drv[dis].ToString();
				//    tmpNd.ImageUrl="../images/"+drv["Caption"].ToString();
				//    tmpNd.NavigateUrl="../"+drv["Caption"].ToString();
				tv.Add(tmpNd);
				if(!firstlevel)
				simpletreeview(tmpNd.Nodes,ds,key,parentkey,dis,keytype,tmpNd.ID,firstlevel,false);
			}
			return rv;
		}

调用示例如下代码:

cs 复制代码
<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="FALSE" %>
<%@ Register TagPrefix="codn" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls"%>
<%@ Import Namespace="System.Data" %>

<script language="C#" runat="server">
    void Page_Load(Object sender, EventArgs e)
    {

        if (Page.IsPostBack) { return; }
        object rvvv=GetDataSet("select acode,aname,parent_acode from pub_area", null);
        DataSet _ds = rvvv as DataSet;
        int rvvv_count = simpletreeview(tv.Nodes, _ds, "acode", "parent_acode", "aname", "uniqueidentifier", "",false,false);
//        Response.Write(rvvv_count);
        return;
    }
 </script>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes"/>
    <title></title>
    </style>
</head>
<body>
<form runat="server">
<div style=" margin-top:50px;margin-left:50px">
       <codn:TreeView ID="tv" runat="server" Height="300" ShowLines="true"  Width="500" AutoPostBack="false" ExpandLevel="3" BackColor="White" style="font-family: 微软雅黑" 
                                EnableTheming="True"  BorderColor="#003300" BorderStyle="Solid" BorderWidth="1px">
        </codn:TreeView>

</div>
 </form>
</body>
 
<script type="text/javascript">
</script>
 
</html>

成功后如下图显示:

根据ID设置节点

SetTreeViewById 方法对当前给定集合进行ID查找,并返回结点ID和选中当前结点,其参数说明见下表:

| 序号 | 参数名 | 类型 | 说明 |
| 1 | tv | Microsoft.Web.UI.WebControls. TreeNodeCollection | 传入的TreeView的当前结点集合对象 |

2 id string 要查找的ID

实现代码如下:

cs 复制代码
public string SetTreeViewById(Microsoft.Web.UI.WebControls.TreeNodeCollection tv,string id)
		{

			string findid="";
			for(int i=0;i<tv.Count;i++)
			{ 
				if(tv[i].ID==id) 
				{ 
					string index1=tv[i].GetNodeIndex();//取得index 
					object tn=tv[i];
					while(tn.GetType()==typeof(Microsoft.Web.UI.WebControls.TreeNode))
					{
                        tn = ((Microsoft.Web.UI.WebControls.TreeNode)tn).Parent;
					}
					if(tn.GetType()==typeof(Microsoft.Web.UI.WebControls.TreeView))
					{
                        ((Microsoft.Web.UI.WebControls.TreeView)tn).SelectedNodeIndex = index1;
					}
					findid=i.ToString();
					break;
				}		
				SetTreeViewById(tv[i].Nodes,id);
			}
			return findid;
}

调用代码如下,本示例要查找南开区(ID为0101)的节点并选中:

cs 复制代码
SetTreeViewById(tv.Nodes, "0101");

成功后如下图:

获取所有结点的索引

GetTreeViewAllNodes 方法获取当前给定集合的所有结点的索引,并存储到指定的ArrayList当中,其参数说明见下表:

| 序号 | 参数名 | 类型 | 说明 |
| 1 | tv | Microsoft.Web.UI.WebControls. TreeNodeCollection | 传入的TreeView的当前结点集合对象 |

2 rv2 ArrayList 要存储的 ArrayList

实现代码如下:

cs 复制代码
public void GetTreeViewAllNodes(Microsoft.Web.UI.WebControls.TreeNodeCollection tv,ArrayList rv2)
{
	for(int i=0;i<tv.Count;i++)
	{ 
		rv2.Add(tv[i].GetNodeIndex());
		GetTreeViewAllNodes(tv[i].Nodes,rv2);
	}

}

调用示例如下,获取南开区的所有街道结点的索引:

cs 复制代码
ArrayList rv2 = new ArrayList();
GetTreeViewAllNodes(tv.Nodes, rv2);
Response.Write(rv2.Count);

小结

1、使用控件前需要下载dll并放置到您的网站bin目录下,可以到我的资源进行下载,链接如下:

https://download.csdn.net/download/michaelline/89267878

2、在 VS 中开发我们需要在 IDE环境解决方案中添加此 dll 并引用,如果使用 System.Web.UI.WebControls.TreeView 则引用 System.Web,如下图:

3、提供一个后端辅助方法 simplebomlist,该方法可以直接从 DataSet 中获得给定查找值的所有下级的关键值信息,并放置到 ArrayList 中。

其参数说明见下表:

| 序号 | 参数名 | 类型 | 说明 |
| 1 | tv | TreeNodeCollection | 要遍历的TreeView集合 |
| 2 | key | string | 关键字段名 |
| 3 | parentkey | string | 父项关键字段名 |
| 4 | initvalue | string | 要查找的关键字段值 |

5 rv2 ArrayList 要存储的 ArrayList 变量

方法代码如下:

cs 复制代码
public void simplebomlist(DataSet ds,string key,string parentkey,string initvalue,ArrayList rv2)
{
	DataView dv=new DataView();
	dv.Table=ds.Tables[0];
	dv.RowFilter="isnull("+parentkey+",'')='"+initvalue+"'";
	foreach(DataRowView drv in dv)
	{
		rv2.Add(drv[key].ToString());
		simplebomlist(ds,key,parentkey,drv[key].ToString(),rv2);
	}
}

方法会在指定的 ArrayList 里存储 关键字段 的 Value 值 。

关于 System.Web.UI.WebControls.TreeView 的使用方法和 Microsoft.Web.UI.WebControls.TreeView 基本一样,只是更换一下控件类型而已,适用于本文的所有方法操作,这里不再赘述。

注意:本文是仅从示例介绍TreeView的使用方法,建议后期使用 System.Web.UI.WebControls.TreeView 进行操作更稳妥一些,详细介绍和用法可参照如下链接:

https://learn.microsoft.com/zh-cn/dotnet/api/system.web.ui.webcontrols.treeview?view=netframework-4.8.1&redirectedfrom=MSDN

感谢您的阅读,希望本文能够对您有所帮助。

相关推荐
kaico20183 分钟前
MySQL的索引
数据库·mysql
GIS之路9 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
勇哥java实战分享10 分钟前
短信平台 Pro 版本 ,比开源版本更强大
后端
是一个Bug12 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213814 分钟前
React面向组件编程
开发语言·前端·javascript
学历真的很重要15 分钟前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn089518 分钟前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪34 分钟前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
持续升级打怪中36 分钟前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路39 分钟前
GDAL 实现矢量合并
前端