VB.NET中如何根据条件为DataTable绑定的DataGrid行设置颜色
问题背景
- 需求:在ASP.NET WebForm的DataGrid控件中,用颜色对应状态字段的字符串值做可视化标识,避免纯文本展示的不直观问题:
cib字段值为EXIST/ACTIVE时,对应内容展示绿色cib字段值为EXIST/INACTIVE时,对应内容展示黄色- 其余异常状态对应内容展示红色
- 现有尝试:参考Color、Brushes类编写了着色逻辑,但运行后着色效果完全不生效,关联代码如下:
hdfAccountNumber.Value = GenericManager.decryptQueryString(Request.QueryString("AccountNumber")) Dim CustomerChannels = GetCustomerDetails(hdfAccountNumber.Value) Dim ussd As String = CustomerChannels.USSD + "/" + CustomerChannels.USSDStatus Dim cib As String = CustomerChannels.CIB + "/" + CustomerChannels.BBGStatus Dim rib As String = CustomerChannels.RIB + "/" + CustomerChannels.RIBStatus Dim mobile As String = CustomerChannels.MOBILEBANKING + "/" + CustomerChannels.NEWMOBILEStatus Dim debitCard As String = CustomerChannels.CardStatus Dim ussdColor As Color Dim cibColor As Color Dim ribColor As Color Dim mobileColor As Color Dim debitCardColor As Color Dim ChannelTable As New DataTable ChannelTable.Columns.Add("USSD") ChannelTable.Columns.Add("CIB") ChannelTable.Columns.Add("RIB") ChannelTable.Columns.Add("MOBILE") ChannelTable.Columns.Add("DEBIT CARD") For Each row As DataGridViewRow In DataGrid1.Rows cib = row.Cells(1).Value If cib = "EXIST/ACTIVE" Then cibColor = Color.Green row.DefaultCellStyle.ForeColor = cibColor ElseIf cib = "EXIST/INACTIVE" Then cibColor = Color.Yellow row.DefaultCellStyle.ForeColor = cibColor Else cibColor = Color.Red row.DefaultCellStyle.ForeColor = cibColor End If ussd = row.Cells(0).Value If ussd = "EXIST/ACTIVE" Then ussdColor = Color.Green row.DefaultCellStyle.ForeColor = ussdColor ElseIf ussd = "EXIST/INACTIVE" Then ussdColor = Color.Yellow row.DefaultCellStyle.ForeColor = ussdColor Else ussdColor = Color.Red row.DefaultCellStyle.ForeColor = ussdColor End If Next ChannelTable.Rows.Add(ussdColor, cibColor, rib, mobile, debitCard) DataGrid1.DataSource = ChannelTable DataGrid1.DataBind()
前端DataGrid控件定义代码:
<asp:UpdatePanel ID="UpdatePanel4" runat="server" class="" style="color:#ffffff; margin-top: 5px; font-size: 12px"> <ContentTemplate> <p style="font-weight: 700; font-weight: 700; margin-left: 10px; font-weight: normal; font-size: 14px;"> Channels<span> <asp:Button ID="availableChannel" runat="server" Text="Get channels" CssClass="tdcolor" /> </span> </p> <asp:DataGrid ID="DataGrid1" runat="server" style="width: 100%; margin-top: -8px; font-weight: 600; border: 1px solid #5c2684;"> </asp:DataGrid> </ContentTemplate> </asp:UpdatePanel>
问题根因
- 控件类型混淆:代码误用WinForm平台的
DataGridViewRow、DefaultCellStyle类与属性,这些API在ASP.NET WebForm的DataGrid控件中不存在,WebForm的DataGrid最终渲染为原生HTML表格,没有上述WinForm专属的样式设置能力 - 执行顺序颠倒:代码先循环遍历DataGrid的行、再执行数据源绑定操作,绑定完成前DataGrid不会生成任何数据行,循环着色逻辑完全不会执行
- 绑定逻辑错误:将系统绘制用的
Color类对象直接存入DataTable数据行,绑定时会被序列化为文本内容展示,无法自动转换为前端样式 - 变量逻辑混乱:初始计算的状态字符串被循环内的单元格值覆盖,最终写入表格的数据源值不准确
修正实现方案
- 调整执行顺序:先构建纯文本状态的DataTable数据源,再触发DataGrid绑定
- 利用DataGrid的
ItemDataBound事件,在逐行绑定数据时,根据单元格存储的状态值直接设置单元格的颜色样式
修正后的代码
前端DataGrid增加OnItemDataBound事件绑定:
<asp:UpdatePanel ID="UpdatePanel4" runat="server" class="" style="color:#ffffff; margin-top: 5px; font-size: 12px"> <ContentTemplate> <p style="font-weight: 700; margin-left: 10px; font-size: 14px;"> Channels<span> <asp:Button ID="availableChannel" runat="server" Text="Get channels" CssClass="tdcolor" /> </span> </p> <asp:DataGrid ID="DataGrid1" runat="server" Width="100%" style="margin-top: -8px; font-weight: 600; border: 1px solid #5c2684;" OnItemDataBound="DataGrid1_ItemDataBound"> </asp:DataGrid> </ContentTemplate> </asp:UpdatePanel>
后台服务端代码调整:
Protected Sub availableChannel_Click(sender As Object, e As EventArgs) Handles availableChannel.Click hdfAccountNumber.Value = GenericManager.decryptQueryString(Request.QueryString("AccountNumber")) Dim CustomerChannels = GetCustomerDetails(hdfAccountNumber.Value) ' 组装纯文本状态值,存入数据源 Dim ussd As String = CustomerChannels.USSD + "/" + CustomerChannels.USSDStatus Dim cib As String = CustomerChannels.CIB + "/" + CustomerChannels.BBGStatus Dim rib As String = CustomerChannels.RIB + "/" + CustomerChannels.RIBStatus Dim mobile As String = CustomerChannels.MOBILEBANKING + "/" + CustomerChannels.NEWMOBILEStatus Dim debitCard As String = CustomerChannels.CardStatus ' 构建纯文本的DataTable结构 Dim ChannelTable As New DataTable ChannelTable.Columns.Add("USSD") ChannelTable.Columns.Add("CIB") ChannelTable.Columns.Add("RIB") ChannelTable.Columns.Add("MOBILE") ChannelTable.Columns.Add("DEBIT CARD") ' 写入纯文本状态行 ChannelTable.Rows.Add(ussd, cib, rib, mobile, debitCard) ' 绑定数据源,触发逐行绑定事件 DataGrid1.DataSource = ChannelTable DataGrid1.DataBind() End Sub ' 逐行处理单元格颜色 Protected Sub DataGrid1_ItemDataBound(sender As Object, e As DataGridItemEventArgs) ' 仅处理数据行,跳过表头、分页栏等非内容行 If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then ' 处理USSD列(第0列)的颜色 Dim ussdStatus = e.Item.Cells(0).Text.Trim() Select Case ussdStatus Case "EXIST/ACTIVE" e.Item.Cells(0).ForeColor = Color.Green Case "EXIST/INACTIVE" e.Item.Cells(0).ForeColor = Color.Yellow Case Else e.Item.Cells(0).ForeColor = Color.Red End Select ' 处理CIB列(第1列)的颜色 Dim cibStatus = e.Item.Cells(1).Text.Trim() Select Case cibStatus Case "EXIST/ACTIVE" e.Item.Cells(1).ForeColor = Color.Green Case "EXIST/INACTIVE" e.Item.Cells(1).ForeColor = Color.Yellow Case Else e.Item.Cells(1).ForeColor = Color.Red End Select End If End Sub
- 扩展提示:如果需要更醒目的展示效果,可将代码中的
ForeColor(文字颜色)替换为BackColor(单元格背景色),实现带底色的状态标签效果。
内容的提问来源于stack exchange,提问作者techstack
相关产品推荐
相关产品推荐

