C# 从 ASP.NET GridView 获取 DataRow

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1306990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:56:38  来源:igfitidea点击:

Getting a DataRow from an ASP.NET GridView

c#asp.netgridviewevent-handlingdatarow

提问by Ian Kemp

I have an ASP.NET GridViewthat's bound to an ObjectDataSource(which is bound to a MySQL database). On this grid, I have 2 unbound ButtonFieldcolumns that I want to trigger server-side events. Hence I have added an eventhandler method to the GridView's RowCommandevent.

我有一个GridView绑定到ObjectDataSource(绑定到 MySQL 数据库)的 ASP.NET 。在这个网格上,我有 2 个未绑定的ButtonField列,我想触发服务器端事件。因此,我在GridView'sRowCommand事件中添加了一个 eventhandler 方法。

In the code of said eventhandler, I need to somehow get hold of the underlying DataRowthat was clicked on by the user. However, I can't seem to get this to work; if I use code like the following the selectedRowvariable is always null:

在所述事件处理程序的代码中,我需要以某种方式获取DataRow用户单击的底层代码。但是,我似乎无法让它发挥作用;如果我使用如下代码,selectedRow变量总是null

protected void searchResultsGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
  CallDataRow selectedRow = (CallDataRow) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].DataItem;
}

I've Googled and found pages such as http://ranafaisal.wordpress.com/2008/03/31/how-to-get-the-current-row-in-gridview-row-command-event, but nothing I've found has worked. I'm pretty sure I'm just missing something obvious, but I can't figure out what...

我用谷歌搜索并找到了诸如http://ranafaisal.wordpress.com/2008/03/31/how-to-get-the-current-row-in-gridview-row-command-event 之类的页面,但我没有'已经发现有效。我很确定我只是遗漏了一些明显的东西,但我不知道是什么......

Here's the ASP.NET code if that helps:

如果有帮助,这里是 ASP.NET 代码:

  <asp:GridView ID="searchResultsGridView" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="PersonNo,CallDate" 
    Width="100%" AllowPaging="True" EnableSortingAndPagingCallbacks="True" 
    onrowcommand="searchResultsGridView_RowCommand" PageSize="20">
    <Columns>
      <asp:BoundField DataField="PersonNo" HeaderText="Account number" ReadOnly="True" 
        SortExpression="PersonNo" />
      <asp:BoundField DataField="AgentNo" HeaderText="Agent number" 
        SortExpression="AgentNo" />
      <asp:BoundField DataField="AgentName" HeaderText="Agent name" 
        SortExpression="AgentName" />
      <asp:BoundField DataField="TelNumber" HeaderText="Telephone number" 
        SortExpression="TelNumber" />
      <asp:BoundField DataField="CallDate" HeaderText="Call date/time" ReadOnly="True" 
        SortExpression="CallDate" />
      <asp:ButtonField CommandName="play" HeaderText="Audio" ShowHeader="True" 
        Text="Play" />
      <asp:ButtonField CommandName="download" Text="Download" />
    </Columns>
  </asp:GridView>

采纳答案by Ian Kemp

Finally got it to work by doing the following:

最终通过执行以下操作使其工作:

  1. Adding a TemplateField containing a bound HiddenField.

    <asp:TemplateField ShowHeader="False">
      <ItemTemplate>
        <asp:HiddenField ID="audioFileName" runat="server" Value='<%# Eval("AudioFileName") %>' />
      </ItemTemplate>
    </asp:TemplateField>
    
  2. Adding the following code in the RowCommand event handler:

    protected void searchResultsGridView_RowCommand(object sender, GridViewCommandEventArgs e)
    {
      string audioFile = ((HiddenField) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("audioFileName")).Value;
    }
    
  1. 添加包含绑定的 HiddenField 的 TemplateField。

    <asp:TemplateField ShowHeader="False">
      <ItemTemplate>
        <asp:HiddenField ID="audioFileName" runat="server" Value='<%# Eval("AudioFileName") %>' />
      </ItemTemplate>
    </asp:TemplateField>
    
  2. 在 RowCommand 事件处理程序中添加以下代码:

    protected void searchResultsGridView_RowCommand(object sender, GridViewCommandEventArgs e)
    {
      string audioFile = ((HiddenField) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("audioFileName")).Value;
    }
    

It's a cludge and it's not particularly secure, but it works and that's all I need right now. Any better solutions are still welcome though...

这是一个障碍,不是特别安全,但它有效,这就是我现在所需要的。尽管如此,仍然欢迎任何更好的解决方案......

回答by Gregtheitroade

 int index = Convert.ToInt32(e.CommandArgument);

 GridViewRow row = searchResultsGridView.Rows[index];

回答by pete

I realize this is 2.5 years late (sorry! didn't see it before...), but I use two static/shared methods to convert the row directly. Maybe this is what you're looking to do?

我意识到这晚了 2.5 年(抱歉!之前没看到...),但我使用两种静态/共享方法直接转换行。也许这就是你想要做的?

VB.Net:

VB.Net:

Public Shared Function GridViewRowToDataRow(ByVal gvr As GridViewRow) As DataRow
    Dim di As Object = Nothing
    Dim drv As DataRowView = Nothing
    Dim dr As DataRow = Nothing

    If gvr IsNot Nothing Then
        di = TryCast(gvr.DataItem, System.Object)
        If di IsNot Nothing Then
            drv = TryCast(di, System.Data.DataRowView)
            If drv IsNot Nothing Then
                dr = TryCast(drv.Row, System.Data.DataRow)
            End If
        End If
    End If

    Return dr
End Function

Public Shared Function GridViewRowEventArgsToDataRow(ByVal e As GridViewRowEventArgs) As DataRow
    Dim gvr As GridViewRow = Nothing
    Dim di As Object = Nothing
    Dim drv As DataRowView = Nothing
    Dim dr As DataRow = Nothing

    If e.Row.RowType = DataControlRowType.DataRow Then
        gvr = TryCast(e.Row, System.Web.UI.WebControls.GridViewRow)
        dr = Helpers.GridViewRowToDataRow(gvr)
    End If

    Return dr
End Function

C#.Net (Converted using: http://www.developerfusion.com/tools/convert/vb-to-csharp/):

C#.Net(转换使用:http: //www.developerfusion.com/tools/convert/vb-to-csharp/):

public static DataRow GridViewRowToDataRow(GridViewRow gvr)
{
    object di = null;
    DataRowView drv = null;
    DataRow dr = null;

    if (gvr != null) {
        di = gvr.DataItem as System.Object;
        if (di != null) {
            drv = di as System.Data.DataRowView;
            if (drv != null) {
                dr = drv.Row as System.Data.DataRow;
            }
        }
    }

    return dr;
}

public static DataRow GridViewRowEventArgsToDataRow(GridViewRowEventArgs e)
{
    GridViewRow gvr = null;
    object di = null;
    DataRowView drv = null;
    DataRow dr = null;

    if (e.Row.RowType == DataControlRowType.DataRow) {
        gvr = e.Row as System.Web.UI.WebControls.GridViewRow;
        dr = Helpers.GridViewRowToDataRow(gvr);
    }

    return dr;
}

回答by RemarkLima

I'm even later to the party! But as I got here from Google, some people may still hit this hence I'll give my answer:

我什至更晚参加聚会!但是当我从谷歌来到这里时,有些人可能仍然会遇到这个问题,因此我会给出我的答案:

protected void SomeDataGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
   if (e.Row.RowType == DataControlRowType.DataRow)
   {
       System.Data.DataRowView dr = (System.Data.DataRowView)e.Row.DataItem;
       string aVar = dr["DataFieldIdLikePlease"].ToString();
   }
}

So then you get can get any of the data fields in the codebehind.

那么你就可以获得代码隐藏中的任何数据字段。

回答by dancl

A clean way to do this seems to be use the "DataKeyNames" property on the GridView. The datasource should contain a column which is a unique identifier or primary key. Then you can set the DataKeyNames property on the gridview to be the name of that property.

一种干净的方法似乎是使用 GridView 上的“DataKeyNames”属性。数据源应包含一个列,该列是唯一标识符或主键。然后您可以将 gridview 上的 DataKeyNames 属性设置为该属性的名称。

The value of that column corresponding to the selected row is then available in the RowCommand and it can be used to make sure the command is applied to the uniquely identified object

与所选行对应的列的值然后在 RowCommand 中可用,它可用于确保命令应用于唯一标识的对象

<asp:GridView ID="gridview" runat="server" ... DataKeyNames="pkey">


protected void gridview_OnRowCommand(object sender, EventArgs e)        
{
    string selectedPkey = null;
    GridViewCommandEventArgs  gridEvent = (GridViewCommandEventArgs)e;
    int index = Convert.ToInt32(gridEvent.CommandArgument);
    if (index >= 0 && index < gridview.Rows.Count)
    {
        GridViewRow r = gridview.Rows[index];
        selectedPkey = gridview.DataKeys[index].Value.ToString();
    }