2009-08-20 71 views
3

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

在上述事件处理程序的代码中,我需要以某种方式获取用户点击的底层DataRow。但是,我似乎无法得到这个工作;如果我使用类似于下面的代码的selectedRow变量始终是null

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

我一派,发现如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> 

回答

4

终于拿到它通过执行以下工作:

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

这是一个cludge,它不是特别安全的,但它的作品,这一切我现在所需要的。任何更好的解决方案仍然欢迎,虽然...

+0

您是否尝试了其他解决方案而没有*** Hidden Fields ***? – Kiquenet 2016-06-29 12:01:03

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

GridViewRow row = searchResultsGridView.Rows[index]; 
+0

这使我ROWTYPE一个GridViewRow == DataRow和DataItem == null。由于这是我需要获取底层DataRow的DataItem,并且在这种情况下DataItem为空,所以这不是一个答案。 – 2009-08-21 11:35:43

+0

你在'RowCommand' ***或***'RowDataBound'中试过了吗? – Kiquenet 2016-06-29 12:00:23

1

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

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(使用转换: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; 
} 
+0

你无法在'void GridResultados_RowCommand(Object sender,GridViewCommandEventArgs e)'事件 – Kiquenet 2016-06-29 12:17:23

1

我甚至后来的党!但是,当我从谷歌来到这里,有些人可能还是打这个所以我给我的答案:

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

,那么你可以得到得到任何的代码隐藏的数据字段。

+2

'RowCommand'中使用*** NOT ***'RowDataBound'? – Kiquenet 2016-06-29 11:57:50

0

干净的方式做到这一点似乎是使用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(); 
    }