Erhalten Sie einen Datarow aus einem ASP.NET -Gridview
-
19-09-2019 - |
Frage
Ich habe ein ASP.NET GridView
das ist an eine gebunden ObjectDataSource
(die an eine MySQL -Datenbank gebunden ist). In diesem Netz habe ich 2 ungebunden ButtonField
Spalten, die ich serverseitige Ereignisse auslösen möchte. Daher habe ich der EventHandler -Methode hinzugefügt GridView
's RowCommand
Veranstaltung.
Im Kodex des genannten EventHandlers muss ich irgendwie das zugrunde liegende bekommen DataRow
Das wurde vom Benutzer angeklickt. Ich kann dies jedoch nicht zum Laufen bringen; Wenn ich Code wie das folgende verwende selectedRow
Variable ist immer null
:
protected void searchResultsGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
CallDataRow selectedRow = (CallDataRow) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].DataItem;
}
Ich habe gegoogelt und Seiten gefunden wie http://ranafaial.wordpress.com/2008/03/31/how-tho-get-the-current-in-in-gridview-row-command-event, Aber nichts, was ich gefunden habe, hat funktioniert. Ich bin mir ziemlich sicher, dass mir nur etwas Offensichtliches fehlt, aber ich kann nicht herausfinden, was ...
Hier ist der ASP.NET -Code, wenn das hilft:
<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>
Lösung
Endlich zum Laufen gebracht, indem es Folgendes ausführte:
Hinzufügen eines Templatefield mit einem gebundenen Hiddenfield.
<asp:TemplateField ShowHeader="False"> <ItemTemplate> <asp:HiddenField ID="audioFileName" runat="server" Value='<%# Eval("AudioFileName") %>' /> </ItemTemplate> </asp:TemplateField>
Hinzufügen des folgenden Codes im RowCommand -Ereignishandler:
protected void searchResultsGridView_RowCommand(object sender, GridViewCommandEventArgs e) { string audioFile = ((HiddenField) searchResultsGridView.Rows[Convert.ToInt32(e.CommandArgument)].FindControl("audioFileName")).Value; }
Es ist ein Cludge und es ist nicht besonders sicher, aber es funktioniert und das ist alles, was ich gerade brauche. Bessere Lösungen sind trotzdem willkommen ...
Andere Tipps
Ich bin noch später zur Party! Aber als ich von Google hier ankam, können einige Leute dies immer noch treffen, daher werde ich meine Antwort geben:
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();
}
}
Dann können Sie alle Datenfelder im Codebehind erhalten.
Mir ist klar, dass dies 2,5 Jahre zu spät ist (Entschuldigung! Ich habe es vorher nicht gesehen ...), aber ich verwende zwei statische/gemeinsame Methoden, um die Zeile direkt umzuwandeln. Vielleicht ist es das, was Sie tun möchten?
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 (konvertiert mit: 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;
}
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = searchResultsGridView.Rows[index];
Eine saubere Möglichkeit, dies zu tun, scheint die Eigenschaft "Datakeynames" in der Gridview zu verwenden. Die DataSource sollte eine Spalte enthalten, die ein eindeutiger Bezeichner oder ein Primärschlüssel ist. Anschließend können Sie die Eigenschaft DataKeynames in der Gridview auf den Namen dieser Eigenschaft einstellen.
Der Wert dieser Spalte, die der ausgewählten Zeile entspricht
<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();
}