Получение DataRow из ASP.NET GridView

У меня есть ASP.NET GridView, привязанный к ObjectDataSource (который привязан к базе данных MySQL). В этой сетке у меня есть 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;
}

Я погуглил и нашел такие страницы, как http://ranafaisal.wordpress.com/2008/03/31/how-to-get-the-current-row-in-gridview-row-command-событие , но ничего из того, что я нашел, не сработало. Я почти уверен, что просто упускаю что-то очевидное, но я не могу понять, что...

Вот код 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>

person Ian Kemp    schedule 20.08.2009    source источник


Ответы (5)


Наконец, он заработал, выполнив следующие действия:

  1. Добавление TemplateField, содержащего связанный HiddenField.

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

Это тупица, и она не особенно безопасна, но она работает, и это все, что мне сейчас нужно. Любые лучшие решения по-прежнему приветствуются...

person Ian Kemp    schedule 24.08.2009
comment
пробовали ли вы другие решения без скрытых полей? - person Kiquenet; 29.06.2016

Я даже позже на вечеринку! Но, поскольку я попал сюда из Google, некоторые люди все еще могут наткнуться на это, поэтому я дам свой ответ:

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

Таким образом, вы можете получить любое из полей данных в отделенном коде.

person RemarkLima    schedule 26.04.2012

Я понимаю, что это с опозданием на 2,5 года (извините! Не видел этого раньше...), но я использую два статических/общих метода для прямого преобразования строки. Может быть, это то, что вы хотите сделать?

ВБ.Нет:

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;
}
person pete    schedule 02.03.2012
comment
нельзя использовать в событии void GridResultados_RowCommand(Object sender, GridViewCommandEventArgs e) - person Kiquenet; 29.06.2016

Кажется, что чистый способ сделать это — использовать свойство 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();
    }
person dancl    schedule 06.07.2016

person    schedule
comment
Это дает мне GridViewRow с RowType == DataRow и DataItem == null. Поскольку для получения базового DataRow мне требуется DataItem, а в данном случае DataItem имеет значение null, это не ответ. - person Ian Kemp; 21.08.2009