C# Web控件与数据感应之 填充 HtmlTable

目录

关于 HtmlTable

HtmlTable与BaseDataList的区别

准备数据源

​范例运行环境

FillTable 方法

设计与实现

模板样例输出

Automatic 模式填充

​         DynamicRows 模式填充

StaticRows 模式填充

小结


关于 HtmlTable

数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,HtmlTable 控件表示为一个服务器控件,隶属于 System.Web.UI.HtmlControls 集合,对于客户端输出即 table 标签元素,table 表格的主要作用就是数据输出 ,本文将介绍 C# 实现操作 HtmlTable 服务器控件实现数据集表数据的轻量化输出与显示。

HtmlTable与BaseDataList的区别

HtmlTable 与诸如 DataGrid、GridView 都可用于数据输出 ,主要区别在于:

(1)前者以属于System.Web.UI.HtmlControls 集合,后者 Microsoft.Web.UI.WebControls 集合

(2)HtmlTable 可实现 table 元素的一些操作,如行、列、单元格及样式设置,而 BaseDataList 除可实现 HtmlTable 的基本控制外,还可以绑定数据源、绑定事件、绑定列控件等更加强大的功能。

(3)对于数据集合访问 HtmlTable 通过 Rows ,列集合为 Cells;而 BaseDataList  通过 Items ,列集合为 Colums。

准备数据源

我们在 MS SQL Server 创建 pub_ChinaPay(支付状态代码表),其结构如下表:

序号字段名类型说明
1valuechar(4)支付状态代码,唯一键
2textnvarchar(14)状态名称
3sortidsmallint排序号

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

CREATE TABLE [dbo].[pub_ChinaPay]([value] [char](4) NOT NULL,[text] [nvarchar](14) NOT NULL,[sortid] [smallint] NULL,CONSTRAINT [PK_pub_ChinaPay] PRIMARY KEY CLUSTERED 
([value] 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语句,创建一些数据:

insert into pub_ChinaPay(value,text,sortid) values('****','默认状态',1)
insert into pub_ChinaPay(value,text,sortid) values('    ','待支付',2)
insert into pub_ChinaPay(value,text,sortid) values('1001','消费交易成功',3)
insert into pub_ChinaPay(value,text,sortid) values('1003','退款提交成功',4)
insert into pub_ChinaPay(value,text,sortid) values('1005','退款撤销成功',5)
insert into pub_ChinaPay(value,text,sortid) values('0003','交易失败',6)
insert into pub_ChinaPay(value,text,sortid) values('6666','微信退款申请成功',7)

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

最后我们将数据填充到 DataReader ,并生成对应的二维数组。

范例运行环境

操作系统: Windows Server 2019 DataCenter

数据库:Microsoft SQL Server 2016

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

开发工具:VS2019  C#

FillTable 方法

设计与实现

FillTable 方法主要是通过 object[,] 二维对象数组数据源进行提取并呈现在 HtmlTable 表格控件上,其参数设置见下表:

序号参数名类型说明
1tbSystem.Web.UI.HtmlControls.HtmlTable要输出的 HtmlTable 对象
2ftFillType

填充模式枚举:

public enum FillType
 { Automatic,DynamicRows,

StaticRows
}

后续将讲解这些模式的区别

3SpaceInEmptyCellbool对于空字符串输出,是否替换为&nbsp 输出以达到更好的显示效果
4MinClearRowsCountint当输出数据行为空时,清除模板表格行的阀值,设为0,则表示全部清空,不显示输出表格的任何元素
5refStartRowIdint指定数据输出的起始行
6refCopyRowIdint指定要复制哪一行的格式进行输出
7allowToHTMLbool是否允许将数据解析为HTML样式输出,默认为 false

GetReaderData 方法可以访问数据库数据表进行查询结果的提取,并转化为 object[,] 二维数组,其参数设置见下表:

序号参数名类型说明
1DbServerTypestring目前支持 "oracle"、 "dm8",其它字符串均视为 MS SQL Server
strConnstring对应数据库的连接字符串
2_sqlstring要执行的SQL语句命令行
3parasArrayList

要赋值的参数对象,逐个添加到ArrayList里,请注意参数为实体数据参数对象,如 MS SQL Server ,请传递如下代码:

ArrayList.Add(new SqlParameter("参数名",参数值)); 

4hastitlebool输出是否包含字段列标题
5ctCommandType

System.Data.CommandType 枚举,可包括:

StoredProcedure(存储过程)
TableDirect(直接表查询)
Text(文本查询)该值为默认值

GetReaderData 方法实现代码如下:

int RowsCount = 0;
int ErrorNum = 0;
string ErrorMessage = "";public object[,] GetReaderData(string DbServerType,string strConn,string _sql,ArrayList paras,bool hastitle,CommandType ct)
{if((DbServerType.ToLower()=="")||(DbServerType.ToLower()=="sqlserver")){SqlConnection Conn = new SqlConnection(strConn );SqlCommand Cmd = new SqlCommand();Cmd.CommandType=ct;Cmd.Connection = Conn;SqlDataReader myDr;Cmd.CommandText =_sql;if(paras!=null){for(int i=0;i<paras.Count;i++){Cmd.Parameters.Add((SqlParameter)paras[i]);}}try{Conn.Open();myDr = Cmd.ExecuteReader();ArrayList rowdata = new ArrayList();int _fieldcount=myDr.FieldCount;Object[] colvalues = new Object[_fieldcount];for(int i=0;i<_fieldcount;i++){colvalues[i]=myDr.GetName(i);}if(hastitle)rowdata.Add(colvalues);while(myDr.Read()){Object[] values = new Object[_fieldcount];myDr.GetValues(values);rowdata.Add(values);RowsCount++;}myDr.Close();object[,] rv=new object[rowdata.Count,_fieldcount];for(int i=0;i<rowdata.Count;i++){for(int j=0;j<_fieldcount;j++){rv[i,j]=((object[])rowdata[i])[j];}}return rv;}catch (SqlException e){ErrorMessage=e.Message;return null;}finally{Conn.Close();Conn.Dispose();}}//sqlserverif(DbServerType.ToLower()=="oracle"){OracleConnection Conn = new OracleConnection(strConn );OracleCommand Cmd = new OracleCommand();Cmd.Connection = Conn;OracleDataReader myDr;Cmd.CommandText =_sql;if(paras!=null){for(int i=0;i<paras.Count;i++){Cmd.Parameters.Add((OracleParameter)paras[i]);}}try{Conn.Open();myDr = Cmd.ExecuteReader();ArrayList rowdata = new ArrayList();int _fieldcount=myDr.FieldCount;Object[] colvalues = new Object[_fieldcount];for(int i=0;i<_fieldcount;i++){colvalues[i]=myDr.GetName(i);}if(hastitle)rowdata.Add(colvalues);while(myDr.Read()){Object[] values = new Object[_fieldcount];myDr.GetValues(values);rowdata.Add(values);RowsCount++;}myDr.Close();object[,] rv=new object[rowdata.Count,_fieldcount];for(int i=0;i<rowdata.Count;i++){for(int j=0;j<_fieldcount;j++){rv[i,j]=((object[])rowdata[i])[j];}}return rv;}catch (OracleException e){ErrorMessage=e.Message;return null;}finally{Conn.Close();Conn.Dispose();}}//oracleif (DbServerType.ToLower() == "dm8"){DmConnection Conn = new DmConnection(strConn);DmCommand Cmd = new DmCommand();Cmd.CommandType = ct;Cmd.Connection = Conn;DmDataReader myDr;Cmd.CommandText = _sql;if (paras != null){for (int i = 0; i < paras.Count; i++){Cmd.Parameters.Add((DmParameter)paras[i]);}}try{Conn.Open();myDr = Cmd.ExecuteReader() as DmDataReader;ArrayList rowdata = new ArrayList();int _fieldcount = myDr.FieldCount;Object[] colvalues = new Object[_fieldcount];for (int i = 0; i < _fieldcount; i++){colvalues[i] = myDr.GetName(i);}if (hastitle)rowdata.Add(colvalues);while (myDr.Read()){Object[] values = new Object[_fieldcount];myDr.GetValues(values);rowdata.Add(values);RowsCount++;}myDr.Close();object[,] rv = new object[rowdata.Count, _fieldcount];for (int i = 0; i < rowdata.Count; i++){for (int j = 0; j < _fieldcount; j++){rv[i, j] = ((object[])rowdata[i])[j];}}return rv;}catch (DmException e){ErrorMessage = e.Message;return null;}finally{Conn.Close();Conn.Dispose();}}//dm8return null;
}//getreaddata

FillTable 方法实现代码如下:

ArrayList paras=new ArrayList();
string refSql="";
bool hastitle=false;
System.Data.CommandType ct=System.Data.CommandType.Text;
public void FillTable(HtmlTable tb, FillType ft, bool SpaceInEmptyCell, int MinClearRowsCount, int refStartRowId,int refCopyRowId,bool allowToHTML){object[,] ReaderData = GetReaderData("SqlServer","您的连接串","",paras,hastitle,ct);if (ReaderData == null && RowsCount==0){while (tb.Rows.Count > MinClearRowsCount){tb.Rows.RemoveAt(tb.Rows.Count - 1);}return;}if (ft == FillType.Automatic || ft==FillType.DynamicRows || ft==FillType.StaticRows){if (ft == FillType.Automatic){int addcells = ReaderData.GetLength(1) - tb.Rows[0].Cells.Count;for (int i = 0; i < tb.Rows.Count; i++){for (int j = 0; j < addcells; j++){HtmlTableCell tc = new HtmlTableCell();if (allowToHTML == true){tc.Attributes.Add("ByHTML", "true");}tb.Rows[i].Cells.Add(tc);}}if (tb.Rows.Count == 2){for (int j = 0; j < ReaderData.GetLength(1); j++){string _fieldname = ReaderData[0, j].ToString();tb.Rows[0].Cells[j].InnerText = _fieldname;}}}int startRowID = tb.Rows.Count - 1;int copyRowID = 0;if (ft == FillType.StaticRows){if (HasTitle == true){startRowID = tb.Rows.Count > 1 ? 1 : 0;}else{startRowID = 0;}}if (refStartRowId != -1) startRowID = refStartRowId;if (refCopyRowId != -1) copyRowID = refCopyRowId;for (int i = (HasTitle == true ? 1 : 0); i < ReaderData.GetLength(0); i++){if (startRowID>tb.Rows.Count-1) break;for (int j = 0; j < ReaderData.GetLength(1); j++){if (j > tb.Rows[copyRowID].Cells.Count - 1) break;HtmlTableCell td = tb.Rows[startRowID].Cells[j];if (td.Attributes["ByHTML"] == null){td.InnerText = ReaderData[i, j].ToString();}else{td.InnerHtml = allowToHTML == true ? (ReaderData[i, j].ToString()) : ReaderData[i, j].ToString();;}if (td.InnerText == "" && SpaceInEmptyCell == true) td.InnerHtml="&nbsp;";}if (i == ReaderData.GetLength(0)-1) break;if (ft == FillType.Automatic || ft == FillType.DynamicRows){HtmlTableRow tr = new HtmlTableRow();tb.Rows.Add(tr);for (int k = 0; k < tb.Rows[copyRowID].Cells.Count; k++){HtmlTableCell prv_tc = tb.Rows[startRowID].Cells[k];HtmlTableCell tc = new HtmlTableCell();tr.Cells.Add(tc);CloneStyles(prv_tc, tc);}}startRowID ++;}}
}//fill table
void CloneStyles(HtmlControl obj, HtmlControl newobj)
{IEnumerator keys = obj.Style.Keys.GetEnumerator();while (keys.MoveNext()){String key = (String)keys.Current; newobj.Style[key] = obj.Style[key];}IEnumerator keys2 = obj.Attributes.Keys.GetEnumerator();while (keys2.MoveNext()){String key = (String)keys2.Current; newobj.Attributes[key] = obj.Attributes[key];}}

模板样例输出

在方法设计的章节里介绍了 FillType (即填充类型的枚举)

Automatic 模式填充

全自动填充,表示行、列均不固定,全由SQL查询结果动态输出,仅设置首行首列的样式即可,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse"><tr><td>标题</td></tr><tr><td>&nbsp;</td></tr>
</table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable, FillType.Automatic, true, 0, 1, 1);

输出结果如下图 

可以看到行列完全由SQL语句决定进行原始输出,行与列均为动态输出 。 

DynamicRows 模式填充

动态行填充,表示行输出不固定,已预知列的输出,仅需要设置首行标题列和数据行的样式即可,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse"><tr><td>状态代码</td><td>状态名称</td><td>排序号</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr></table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable, FillType.DynamicRows, true, 0, 1, 1);

输出结果如下图 

可以看到行为动态输出,标题列为预期的设置 。 

StaticRows 模式填充

静态填充,表示行、列均固定,由SQL查询结果根据预设输出,可设置每行每列的样式,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse"><tr><td>状态代码</td><td>状态名称</td><td>排序号</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr></table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable,FillType.StaticRows, true, 0, 1, 1);

输出结果如下图 

可以看到行有冗余,因此静态行模式仅输出列和行的可见区域,即溢出和不足均不显示 。 

小结

关于 HtmlTable 的其它详细操作和介绍,可参照如下链接:

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

关于填充模式,是在实际的应用场景里进行输出 ,比如全动态适合于依赖SQL语句控制度较高的场景,而动态行则是比较常见的一种输出方式,静态行输出则比如我们提供一种填写表格,已经预设好最大行数,为体现整体统一的输出风格而应用。所以,我们可以根据自己的实际需要改造输出 的模式,本示例代码仅供您参考。 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电商行业为什么要分析竞争商品?详解竞争商品分析八个维度

在当今的电子商务领域&#xff0c;竞争日益激烈&#xff0c;消费者拥有几乎无限的选择。品牌和商家为了在这场竞争中获得优势&#xff0c;必须深入理解市场动态、消费者需求以及竞争对手的策略。分析竞争商品是实现这一目标的关键步骤。它不仅帮助商家揭示行业内表现优异商品的…

【机器学习基础】Python编程03:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…

LW-DETR:实时目标检测的Transformer, Apache-2.0 开源可商用,实验超 YOLOv8

LW-DETR&#xff1a;实时目标检测的Transformer&#xff0c; Apache-2.0 开源可商用&#xff0c;实验超 YOLOv8 LW-DETR 架构实例化高效训练高效推理 目的与解法拆解ViT编码器和DETR解码器多级特征图聚合变形交叉注意力窗口注意力和全局注意力 论文&#xff1a;https://arxiv.o…

使用docker部署前后端

1.首先&#xff0c;已经默认拥有了一个拥有docker和docker compose的linux服务器。 本篇文章部署的是SpringBootVue前后端分离项目&#xff0c;用了docker compose&#xff0c;但不多。 2.数据库 使用命令&#xff08;表示拉取最新的MySQL) docker pull mysql:latest如果想指定…

64. UE5 RPG 创建新的双手攻击怪物

在上一篇文章中&#xff0c;我们实现了新的功能&#xff0c;现在可以创建多个普通攻击动画&#xff0c;并且可以根据你所使用的普通攻击动画&#xff0c;设置不同的攻击位置。比如&#xff0c;你使用武器&#xff0c;那么攻击位置需要从武器上获取&#xff0c;如果你没有持有武…

Python怎么安装gym:一份详尽的指南

Python怎么安装gym&#xff1a;一份详尽的指南 在Python的机器学习生态系统中&#xff0c;gym库是一个至关重要的组件&#xff0c;它为我们提供了用于开发和比较强化学习算法的标准环境。然而&#xff0c;安装gym可能并不总是那么直接&#xff0c;尤其是对于那些刚开始接触这个…

LangChain学习之四种Memory模式使用

1. 学习背景 在LangChain for LLM应用程序开发中课程中&#xff0c;学习了LangChain框架扩展应用程序开发中语言模型的用例和功能的基本技能&#xff0c;遂做整理为后面的应用做准备。视频地址&#xff1a;基于LangChain的大语言模型应用开发构建和评估。 2. 四种memory模式 …

Qt Creator创建Python界面工程并打包为可执行exe文件

Qt Creator创建Python界面工程并打包为可执行exe文件_qtcreator创建python工程-CSDN博客

【QT】Qt Plugin开发

目录 插件是什么QT插件是什么 为什么要有插件开发插件开发优势插件和动态库区别 Qt PluginQT插件类型QT插件开发流程QT插件应用QT插件JSON文件 参考文章 插件是什么 插件(Plug-in,又称addin、add-in、addon或add-on,又译外挂)是一种遵循一定规范的应用程序接口编写出来的程序。…

C#中的as和is

在 C# 中&#xff0c;as 和 is 是用于类型转换和类型检查的操作符。 as 操作符&#xff1a; as 操作符用于尝试将一个对象转换为指定的引用类型或可空类型&#xff0c;如果转换失败&#xff0c;将返回 null。语法&#xff1a;expression as type示例&#xff1a; object obj &…

把文件从一台linux机器上传到另一台linux机器上

文章目录 1&#xff0c;第一种情况1.1 先测试2台机器是否可以互相通信1.2 对整个文件夹里面的所有内容进行传输的命令1.3 检查结果 2&#xff0c;第二种情况2.1&#xff0c;单个文件传输的命令 1&#xff0c;第一种情况 我这里有2台linux机器&#xff0c; 机器A&#xff1a;19…

高科技IT企业适合平滑替代FTP升级方案有哪些?

随着信息技术的飞速发展&#xff0c;传统的文件传输协议FTP已经逐渐不能满足现代企业的需求。特别是对于高科技IT企业来说&#xff0c;他们需要的不仅仅是一个简单的文件传输工具&#xff0c;而是一个能够提供高速、安全、稳定、易管理且兼容性强的解决方案。那么&#xff0c;在…

JFinal学习

JFinal 1、基于 JFinal 的 web 项目需要创建一个继承自 JFinalConfig 类的子类&#xff0c;该类用于对整个 web 项目进行配置。 JFinalConfig 子类需要实现六个抽象方法&#xff1a; 1&#xff09;configConstant(Constants me) 此方法用来配置 JFinal 常量值&#xff0c;如开…

数学建模 —— 聚类分析(3)

目录 一、聚类分析概述 1.1 常用聚类要素的数据处理 1.1.1 总和标准化 1.1.2 标准差标准化 1.1.3 极大值标准化 1.1.4 极差的标准化 1.2 分类 1.2.1 快速聚类法&#xff08;K-均值聚类&#xff09; 1.2.2 系统聚类法&#xff08;分层聚类法&#xff09; 二、分类统计…

QPainter::end: Painter ended with 2 saved states 如何解决

QPainter::end: Painter ended with 2 saved states 是一个警告信息&#xff0c;它表明 QPainter 对象在结束时还存在未恢复的状态栈。这通常发生在 QPainter 对象被销毁&#xff08;即调用其析构函数&#xff09;时&#xff0c;如果存在未通过 restore() 方法平衡掉的 save() …

AutoMQ 生态集成 Tigris

Tigris[1]是一个全球分布式的兼容 S3 的对象存储服务&#xff0c;它允许你存储和访问任意数量的数据&#xff0c;具有广泛的使用场景。Tigris 会自动且智能地将数据分布到靠近用户的位置&#xff0c;让用户无需担心数据复制和缓存复杂性。 你可以将 Tigris 用于多种场景&#x…

EEPROM 怎么选

选择合适的EEPROM型号需要考虑多个因素&#xff0c;包括容量、供应商、性能参数、价格、可用性和兼容性等。以下是一个详细的步骤指南&#xff0c;帮助您在众多品牌和型号中做出选择&#xff1a; 1. 确定基本需求 首先确定您的应用对EEPROM的基本需求&#xff1a; 容量&…

Python里cv2是什么包?怎么安装使用?

在Python中&#xff0c;cv2是OpenCV库的模块名。OpenCV&#xff08;全称Open Source Computer Vision Library&#xff09;是一个基于开源的计算机视觉库&#xff0c;它提供了大量的图像处理和计算机视觉算法&#xff0c;如图像滤波、边缘检测、图像分割、特征提取、目标检测等…

快速排序——AcWing785.快速排序

AcWing785.快速排序 题目描述 785. 快速排序 - AcWing题库 运行代码 #include <iostream> #include <algorithm> using namespace std; const int N 1e66; int q[N]; void quick_sort(int q[], int l, int r) {if (l > r) return;int m l r >> 1;//…

LeetCode刷题之HOT100之不同路径

2024/6/6 小雨&#xff0c;没停。明天就要高考啦&#xff0c;回想五年前我也带着紧张与期待走过这些天&#xff0c;祝高考学子一切顺利。Anyway&#xff0c;早上一到实验室我就去看望我的栀子花&#xff0c;带着满怀的期待去看它长大了多少&#xff0c;是的&#xff0c;花苞还在…