You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework 4.8中为GridView行添加额外数据的替代方案

问题描述

我通过构建DataTable作为GridView的数据源展示数据,代码如下:

DataTable details = new DataTable();
details.Columns.Add("Name");
details.Columns.Add("Cost");
details.Columns.Add("Time");
foreach(Source s in MySource){
    DataRow detailRow = details.NewRow();
    detailRow["Id"] = 10;
    detailRow["Name"] = "test";
    detailRow["Cost"] = 10;
    detailRow["Time"] = s.GetSimplifiedTime();
    details.Rows.Add(detailRow);
}

myGrid.DataSource = details ;
myGrid.DataBind();

现在需要为每行的部分列保存额外数据(比如显示08/01对应的精确时间08/01/2023 10:23:11),并在RowSelecting事件处理器中使用这些数据。

目前我想到的方法是添加额外的DataKeys列,但这不符合DataKey的设计初衷,而且我已经把Id作为唯一标识符了:

<asp:GridView ID="myGrid" DataKeyNames="ID, DetailedTime, FullName" runat="server" CssClass="table table-hover" AutoGenerateColumns="false"  OnSelectedIndexChanged="MyHandler">
    <Columns>
        <asp:CommandField HeaderText="Process" ShowSelectButton="True" ButtonType="Button" ControlStyle-CssClass="btn btn-outline-success"/>
        <asp:BoundField DataField="Name" HeaderText="Name"></asp:BoundField>
        <asp:BoundField DataField="Cost" HeaderText="Cost"></asp:BoundField>
        <asp:BoundField DataField="Time" HeaderText="Due"></asp:BoundField>
    </Columns>
</asp:GridView>

我想知道有没有其他方法可以为每行添加额外数据?更理想的是能为每个单元格添加数据,方便分别访问显示文本(如Cells[0].Text)和实际值(如Cells[0].Value)。我使用的是.NET Framework 4.8。


可行解决方案

方法1:在DataTable中添加隐藏列

直接在DataTable里新增存储额外数据的列,然后在GridView中将这些列设置为隐藏,既不影响页面显示,又能在事件中轻松获取数据。

修改DataTable代码:

DataTable details = new DataTable();
details.Columns.Add("Name");
details.Columns.Add("Cost");
details.Columns.Add("Time");
// 添加隐藏列存储精确时间
details.Columns.Add("DetailedTime", typeof(DateTime));
foreach(Source s in MySource){
    DataRow detailRow = details.NewRow();
    detailRow["Id"] = 10;
    detailRow["Name"] = "test";
    detailRow["Cost"] = 10;
    detailRow["Time"] = s.GetSimplifiedTime();
    // 存入精确时间数据
    detailRow["DetailedTime"] = s.GetExactTime();
    details.Rows.Add(detailRow);
}

myGrid.DataSource = details ;
myGrid.DataBind();

修改GridView配置:

在Columns节点中添加隐藏列,设置Visible="false":

<asp:GridView ID="myGrid" DataKeyNames="ID" runat="server" CssClass="table table-hover" AutoGenerateColumns="false"  OnSelectedIndexChanged="MyHandler">
    <Columns>
        <asp:CommandField HeaderText="Process" ShowSelectButton="True" ButtonType="Button" ControlStyle-CssClass="btn btn-outline-success"/>
        <asp:BoundField DataField="Name" HeaderText="Name"></asp:BoundField>
        <asp:BoundField DataField="Cost" HeaderText="Cost"></asp:BoundField>
        <asp:BoundField DataField="Time" HeaderText="Due"></asp:BoundField>
        <!-- 隐藏列存储精确时间,前端不显示 -->
        <asp:BoundField DataField="DetailedTime" Visible="false"></asp:BoundField>
    </Columns>
</asp:GridView>

在事件中获取数据:

protected void MyHandler(object sender, EventArgs e)
{
    GridViewRow selectedRow = myGrid.SelectedRow;
    // 方式1:通过单元格索引获取
    DateTime detailedTime = Convert.ToDateTime(selectedRow.Cells[4].Text);
    // 方式2:通过DataRowView直接读取DataTable列
    DataRowView rowView = (DataRowView)selectedRow.DataItem;
    DateTime detailedTime = (DateTime)rowView["DetailedTime"];
}

方法2:利用RowDataBound事件将额外数据存入控件Attributes

如果需要为单个单元格绑定显示文本和实际值,可以在RowDataBound事件中,把额外数据存入单元格或子控件的Attributes集合中,相当于给元素加自定义属性。

代码示例:

protected void myGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DataRowView rowView = (DataRowView)e.Row.DataItem;
        // 获取时间列对应的单元格
        TableCell timeCell = e.Row.Cells[3];
        // 将精确时间存入单元格的自定义属性
        timeCell.Attributes["data-detailed-time"] = rowView["DetailedTime"].ToString();
        
        // 如果用TemplateField嵌套Label控件,也可以存到Label的Attributes里
        // Label timeLabel = (Label)e.Row.FindControl("timeLabel");
        // timeLabel.Attributes["data-detailed-time"] = rowView["DetailedTime"].ToString();
    }
}

在事件中获取数据:

protected void MyHandler(object sender, EventArgs e)
{
    GridViewRow selectedRow = myGrid.SelectedRow;
    TableCell timeCell = selectedRow.Cells[3];
    string detailedTimeStr = timeCell.Attributes["data-detailed-time"];
    DateTime detailedTime = DateTime.Parse(detailedTimeStr);
}

方法3:用TemplateField替代BoundField,直接绑定控件属性

通过TemplateField可以更灵活地控制单元格内容,同时给内部控件添加自定义属性来存储额外数据,完美实现"显示文本+实际值"的需求。

修改GridView配置:

<asp:GridView ID="myGrid" DataKeyNames="ID" runat="server" CssClass="table table-hover" AutoGenerateColumns="false"  OnSelectedIndexChanged="MyHandler">
    <Columns>
        <asp:CommandField HeaderText="Process" ShowSelectButton="True" ButtonType="Button" ControlStyle-CssClass="btn btn-outline-success"/>
        <asp:BoundField DataField="Name" HeaderText="Name"></asp:BoundField>
        <asp:BoundField DataField="Cost" HeaderText="Cost"></asp:BoundField>
        <asp:TemplateField HeaderText="Due">
            <ItemTemplate>
                <!-- Text绑定显示的简化时间,自定义属性绑定精确时间 -->
                <asp:Label ID="timeLabel" runat="server" Text='<%# Eval("Time") %>' data-detailed-time='<%# Eval("DetailedTime") %>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

在事件中获取数据:

protected void MyHandler(object sender, EventArgs e)
{
    GridViewRow selectedRow = myGrid.SelectedRow;
    Label timeLabel = (Label)selectedRow.FindControl("timeLabel");
    // 读取自定义属性里的精确时间
    string detailedTimeStr = timeLabel.Attributes["data-detailed-time"];
    DateTime detailedTime = DateTime.Parse(detailedTimeStr);
}

方法4:将原始数据源存入ViewState/Session(适合小数据量)

如果MySource的数据量不大,可以把原始数据源存储到ViewState或Session中,在RowSelecting事件里通过行索引直接获取原始对象的完整数据,不用额外处理DataTable。

存储数据源:

// 绑定DataTable前先把原始数据源存到ViewState
ViewState["MySource"] = MySource;

DataTable details = new DataTable();
// 构建DataTable的代码保持不变

在事件中获取原始数据:

protected void myGrid_SelectedIndexChanged(object sender, EventArgs e)
{
    int selectedIndex = myGrid.SelectedIndex;
    List<Source> sourceList = (List<Source>)ViewState["MySource"];
    Source selectedSource = sourceList[selectedIndex];
    // 直接调用原始对象的方法获取精确时间
    DateTime detailedTime = selectedSource.GetExactTime();
}

内容的提问来源于stack exchange,提问作者SyndRain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:55:01