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
Getting a DataRow from an ASP.NET GridView
提问by Ian Kemp
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.
我有一个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 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
:
在所述事件处理程序的代码中,我需要以某种方式获取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:
最终通过执行以下操作使其工作:
Adding a TemplateField containing a bound HiddenField.
<asp:TemplateField ShowHeader="False"> <ItemTemplate> <asp:HiddenField ID="audioFileName" runat="server" Value='<%# Eval("AudioFileName") %>' /> </ItemTemplate> </asp:TemplateField>
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; }
添加包含绑定的 HiddenField 的 TemplateField。
<asp:TemplateField ShowHeader="False"> <ItemTemplate> <asp:HiddenField ID="audioFileName" runat="server" Value='<%# Eval("AudioFileName") %>' /> </ItemTemplate> </asp:TemplateField>
在 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();
}