从 ASP.NET GridView 获取 DataRow

发布于 2024-08-02 14:58:00 字数 2079 浏览 11 评论 0 原文

我有一个绑定到 ObjectDataSource (绑定到 MySQL 数据库)的 ASP.NET GridView。在此网格上,我有 2 个未绑定的 ButtonField 列,我想要触发服务器端事件。因此,我向 GridView 的 RowCommand 事件添加了一个事件处理程序方法。

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

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

我在 Google 上搜索并找到了诸如 http://ranafaisal.wordpress.com/2008/03 /31/how-to-get-the-current-row-in-gridview-row-command-event,但我发现没有任何效果。我很确定我只是错过了一些明显的东西,但我不知道是什么......

这是 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>

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

In the code of said eventhandler, I need to somehow get hold of the underlying DataRow that was clicked on by the user. However, I can't seem to get this to work; if I use code like the following the selectedRow variable is always 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...

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

  <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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤芳又自赏 2024-08-09 14:58:01

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

VB.Net:C#.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

(使用以下方式转换: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;
}

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?

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/):

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;
}
诗笺 2024-08-09 14:58:01
 int index = Convert.ToInt32(e.CommandArgument);

 GridViewRow row = searchResultsGridView.Rows[index];
 int index = Convert.ToInt32(e.CommandArgument);

 GridViewRow row = searchResultsGridView.Rows[index];
蘸点软妹酱 2024-08-09 14:58:01

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

然后,与所选行对应的该列的值可在 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();
    }

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.

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

<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();
    }
北方。的韩爷 2024-08-09 14:58:00

最后通过执行以下操作使其正常工作:

  1. 添加包含绑定 HiddenField 的 TemplateField。

    
      <项目模板>
        >
      
    
    
  2. 在 RowCommand 事件处理程序中添加以下代码:

    protected void searchResultsGridView_RowCommand(对象发送者,GridViewCommandEventArgs e)
    {
      字符串audioFile = ((HiddenField) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("audioFileName")).Value;
    }
    

这是一个障碍,而且不是特别安全,但它可以工作,这就是我现在所需要的。但仍然欢迎任何更好的解决方案......

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;
    }
    

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...

奈何桥上唱咆哮 2024-08-09 14:58:00

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

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();
   }
}

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文