ASP.NET - 使用 RowCommand 时获取当前行的 DropDownList SelectedValue
ASP.NET - Get DropDownList SelectedValue for current Row when using RowCommand
当我 运行 来自 gridview 行上按钮的行命令事件时
可以从事件行上找到的任何字段中检测到正确的值。
hidID
这是一个唯一标识符,每行都正确报告为
预期。
ddlVal
总是报告列表中的第一项而不是
当前选择的值。
任何人都可以解释为什么下拉列表不会
使用命令事件时检测当前选择的值?
ASP.NET
<asp:GridView ID="gv" runat="Server" AutoGenerateColumns="False" OnRowCommand="gv_RowCommand" EnableModelValidation="False">
<Columns>
<asp:TemplateField HeaderText="Reason Missed" ItemStyle-CssClass="Inline" HeaderStyle-CssClass="NoSort" Visible="false">
<ItemTemplate>
<asp:DropDownList ID="ddl" runat="server" DataSourceID="sqldatasource" DataValueField="ID" DataTextField="Text" AppendDataBoundItems="true">
<asp:ListItem Text="Select ..." Value="0"/>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sqldatasource" runat="Server" SelectCommand="sp" SelectCommandType="StoredProcedure"/>
VB
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim constring = ConfigurationManager.ConnectionStrings("Con").ConnectionString
sqldatasource.ConnectionString = constring
Bind_gv()
End Sub
Protected Sub gv_RowCommand(sender As Object, e As GridViewCommandEventArgs)
Dim rowIndex As Integer = Convert.ToInt32(e.CommandArgument)
Dim row As GridViewRow = gv.Rows(rowIndex)
Dim ddlVal As Integer = DirectCast(row.FindControl("ddl"), DropDownList).SelectedValue
Dim hidID As Integer = DirectCast(row.FindControl("hidID"), HiddenField).Value
'ETC ...
End Sub
经过进一步诊断,我发现:
- 行命令事件首先重新加载页面。
- 这会触发页面生命周期。
RowCommand
事件在Page_Load
事件之后触发。
RowCommand
事件在PreRender
事件之前触发。
这样做的结果是,如果您在 Page_Load
事件中绑定数据,那么在触发 RowCommand
之前,该数据是 bound/rebound。
如果像我的情况一样,您在 Page_Load
事件中绑定下拉列表或在 Page_Load
中绑定 gridview 和 sqldatasource,那么在RowCommand
被触发,因为它们将重置为初始值。
回答
在 RowCommand
触发后(例如 OnPreRenderComplete
),在任何情况下都绑定您的 gridview。这样,在触发 RowCommand
事件之前,客户端更改仍然可用。
当我 运行 来自 gridview 行上按钮的行命令事件时 可以从事件行上找到的任何字段中检测到正确的值。
hidID
这是一个唯一标识符,每行都正确报告为 预期。ddlVal
总是报告列表中的第一项而不是 当前选择的值。任何人都可以解释为什么下拉列表不会 使用命令事件时检测当前选择的值?
ASP.NET
<asp:GridView ID="gv" runat="Server" AutoGenerateColumns="False" OnRowCommand="gv_RowCommand" EnableModelValidation="False">
<Columns>
<asp:TemplateField HeaderText="Reason Missed" ItemStyle-CssClass="Inline" HeaderStyle-CssClass="NoSort" Visible="false">
<ItemTemplate>
<asp:DropDownList ID="ddl" runat="server" DataSourceID="sqldatasource" DataValueField="ID" DataTextField="Text" AppendDataBoundItems="true">
<asp:ListItem Text="Select ..." Value="0"/>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sqldatasource" runat="Server" SelectCommand="sp" SelectCommandType="StoredProcedure"/>
VB
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim constring = ConfigurationManager.ConnectionStrings("Con").ConnectionString
sqldatasource.ConnectionString = constring
Bind_gv()
End Sub
Protected Sub gv_RowCommand(sender As Object, e As GridViewCommandEventArgs)
Dim rowIndex As Integer = Convert.ToInt32(e.CommandArgument)
Dim row As GridViewRow = gv.Rows(rowIndex)
Dim ddlVal As Integer = DirectCast(row.FindControl("ddl"), DropDownList).SelectedValue
Dim hidID As Integer = DirectCast(row.FindControl("hidID"), HiddenField).Value
'ETC ...
End Sub
经过进一步诊断,我发现:
- 行命令事件首先重新加载页面。
- 这会触发页面生命周期。
RowCommand
事件在Page_Load
事件之后触发。RowCommand
事件在PreRender
事件之前触发。
这样做的结果是,如果您在 Page_Load
事件中绑定数据,那么在触发 RowCommand
之前,该数据是 bound/rebound。
如果像我的情况一样,您在 Page_Load
事件中绑定下拉列表或在 Page_Load
中绑定 gridview 和 sqldatasource,那么在RowCommand
被触发,因为它们将重置为初始值。
回答
在 RowCommand
触发后(例如 OnPreRenderComplete
),在任何情况下都绑定您的 gridview。这样,在触发 RowCommand
事件之前,客户端更改仍然可用。