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…

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

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

把文件从一台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;在…

数学建模 —— 聚类分析(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; 二、分类统计…

AutoMQ 生态集成 Tigris

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

快速排序——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;花苞还在…

《开源模型食用指南》基于Linux环境快速部署开源模型,更适合中国宝宝的部署教程

今天给大家推荐一个非常适合中国宝宝学习的专属大模型教程&#xff0c;也就是它《开源模型食用指南》&#xff01; 当前百模大战正值火热&#xff0c;开源LLM层出不穷。 如今国内外已经涌现了众多优秀开源LLM&#xff0c;国外如LLaMA、Alpaca&#xff0c;国内如ChatGLM、BaiCh…

想了解Prompt 技术?看这篇就够了!

最近看了 Meta-Prompt&#xff0c;发现 Prompt 的技术已经发展了几代了。真的要好好梳理一下了。首先是官方有 一个自己的 Prompt engineer &#xff0c; 这个是一定要认真学习的。 https://platform.openai.com/docs/guides/prompt-engineering 官方建议&#xff1a; 写作清…

使用pexpect检查SSH上的文件是否存在

使用 pexpect 模块可以在 Python 中执行命令并检查其输出。你可以使用 ssh 命令连接到远程服务器&#xff0c;并执行 ls 命令检查文件是否存在。下面我就列举几个我经常遇到的几个错误并做个详细的解决方案。 1、问题背景 用户需要编写一个 Python 脚本&#xff0c;以检查一个…

python面向过程与初始面向对象编程

让我们穿越到《龙珠》世界&#xff0c;一起揭开 面向对象编程 的神秘面纱吧。 面向过程编程与面向对象编程 天下第一武道会 选手登记 第 22 届天下第一武道会即将召开&#xff0c;各路武术高手齐聚一堂&#xff0c;其中最受瞩目的&#xff0c;当属卡卡罗特&#xff08;孙悟…

我的创作纪念日--我和CSDN一起走过的1825天

机缘 第一次在CSDN写文章&#xff0c;是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记&#xff0c;没有去和大家区分享的想法&#xff0c;是一起的朋…

C++第二十四弹---从零开始模拟STL中的list(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、基本结构 2、基本函数实现 2.1、默认构造函数 2.2、尾插数据 3、迭代器的封装 3.1、迭代器的基本结构 3.2、迭代器重载函数的实现 4、迭…

大家都在用的4款超实用视频剪辑软件,快来码住自用吧!

随着自媒体行业的不断发展&#xff0c;不少小伙伴也逐渐步入了短视频的热潮。对于短视频制作来说&#xff0c;视频剪辑软件的选择非常重要。 如果剪辑软件不够好&#xff0c;整个视频就基本垮掉了。今天就给大家推荐4款好用的视频剪辑软件。 1.牛学长视频剪辑 推荐剪辑新手入门…

win11通过网线分享网络到Ubuntu工控机

1.条件&#xff1a;一个能无线联网的win11&#xff0c;一根网线&#xff0c;一台Ubuntu工控机&#xff0c;并且使用网线连接两者 2.在win11电脑上 2.1 打开控制面板的网络和Internet 2.2 进入网络和共享中心&#xff0c;在左侧进入 更改适配器设置 2.3 在WLAN上右键&#xff0…

如何通过Python SMTP配置示例发附件邮件?

Python SMTP配置的步骤&#xff1f;SMTP服务器的优缺点有哪些&#xff1f; 当我们需要发送包含附件的邮件时&#xff0c;自动化的解决方案显得尤为重要。Python提供了SMTP库&#xff0c;使我们能够轻松配置并发送带有附件的邮件。AokSend将通过一个示例来展示如何操作&#xf…

AIGC会带来失业潮吗?紧紧跟时代第一步,如何学习AIGC

会&#xff0c;但AI淘汰的始终是跟不上时代的人。 现在很多公司都有AI培训&#xff0c;不仅GPT&#xff0c;还有Midjourney、Stable DIffusion等一系列AI工具。 像我们公司虽然今年招的少&#xff0c;但也会对新招的应届生统一进行AI培训。 用任正非先生的话来说就是&#x…