添加新行后GridView中DropDownList重置:如何保留状态并刷新NoTagging
解决GridView中DropDownList选中状态丢失问题
问题根源
- 启用
AutoPostBack="True"后,下拉框选值触发回发,但未将ddlItem的选中值保存到ViewState的CurrentTable中 SetPreviousData方法仅恢复了ddlNoTagging的选中状态,完全忽略ddlItem的状态恢复- GridView重新绑定时,
ddlItem通过SqlDataSource重新加载数据,但未从保存的状态中恢复选中值
解决方案
1. 扩展ViewState的DataTable,保存下拉框选中值
修改SetInitialRow方法,新增列存储两个下拉框的选中值:
Private Sub SetInitialRow() Dim dt As DataTable = New DataTable() dt.Columns.Add(New DataColumn("RowNumber", GetType(String))) dt.Columns.Add(New DataColumn("SelectedKodItem", GetType(String))) ' 存储ddlItem选中值 dt.Columns.Add(New DataColumn("SelectedNoTagging", GetType(String))) ' 存储ddlNoTagging选中值 Dim dr As DataRow = dt.NewRow() dr("RowNumber") = 1 dr("SelectedKodItem") = String.Empty dr("SelectedNoTagging") = String.Empty dt.Rows.Add(dr) ViewState("CurrentTable") = dt Gridview1.DataSource = dt Gridview1.DataBind() Dim ddl1 As DropDownList = CType(Gridview1.Rows(0).Cells(1).FindControl("ddlItem"), DropDownList) Dim ddl2 As DropDownList = CType(Gridview1.Rows(0).Cells(2).FindControl("ddlNoTagging"), DropDownList) ' 无需手动填充,依赖SqlDataSource自动加载数据 End Sub
2. 下拉框选值变化时,保存状态到ViewState
修改ddlItem_SelectedIndexChanged方法,同步更新ViewState中的选中值:
Protected Sub ddlItem_SelectedIndexChanged(sender As Object, e As EventArgs) Dim ddlItem As DropDownList = CType(sender, DropDownList) Dim row As GridViewRow = CType(ddlItem.NamingContainer, GridViewRow) Dim ddlNoTagging As DropDownList = CType(row.FindControl("ddlNoTagging"), DropDownList) ' 保存ddlItem选中值到ViewState If ViewState("CurrentTable") IsNot Nothing Then Dim dt As DataTable = CType(ViewState("CurrentTable"), DataTable) dt.Rows(row.RowIndex)("SelectedKodItem") = ddlItem.SelectedValue ViewState("CurrentTable") = dt End If ' 保留原有的ddlNoTagging刷新逻辑 Dim sqlListTagging As SqlDataSource = CType(row.FindControl("sqlListTagging"), SqlDataSource) sqlListTagging.SelectParameters("KodItem").DefaultValue = ddlItem.SelectedValue ddlNoTagging.DataBind() End Sub
3. 完善状态恢复逻辑,同时恢复两个下拉框
修改SetPreviousData方法,同时恢复ddlItem和ddlNoTagging的选中状态:
Private Sub SetPreviousData() Dim rowIndex As Integer = 0 If ViewState("CurrentTable") IsNot Nothing Then Dim dt As DataTable = CType(ViewState("CurrentTable"), DataTable) If dt.Rows.Count > 0 Then For i As Integer = 0 To dt.Rows.Count - 1 Dim ddl1 As DropDownList = CType(Gridview1.Rows(rowIndex).Cells(1).FindControl("ddlItem"), DropDownList) Dim ddl2 As DropDownList = CType(Gridview1.Rows(rowIndex).Cells(2).FindControl("ddlNoTagging"), DropDownList) If ddl1 IsNot Nothing AndAlso ddl2 IsNot Nothing Then ' 恢复ddlItem选中值 Dim savedKodItem As String = dt.Rows(i)("SelectedKodItem").ToString() If Not String.IsNullOrEmpty(savedKodItem) Then Dim itemToSelect As ListItem = ddl1.Items.FindByValue(savedKodItem) If itemToSelect IsNot Nothing Then itemToSelect.Selected = True ' 联动刷新ddlNoTagging并恢复其选中值 Dim sqlListTagging As SqlDataSource = CType(Gridview1.Rows(rowIndex).Cells(2).FindControl("sqlListTagging"), SqlDataSource) sqlListTagging.SelectParameters("KodItem").DefaultValue = savedKodItem ddl2.DataBind() Dim savedNoTagging As String = dt.Rows(i)("SelectedNoTagging").ToString() If Not String.IsNullOrEmpty(savedNoTagging) Then Dim taggingItem As ListItem = ddl2.Items.FindByValue(savedNoTagging) If taggingItem IsNot Nothing Then taggingItem.Selected = True End If End If End If End If End If rowIndex += 1 Next End If End If End Sub
4. 新增行时维护空状态值
修改AddNewRowToGrid方法,确保新增行的状态列有初始值:
Private Sub AddNewRowToGrid() If ViewState("CurrentTable") IsNot Nothing Then Dim dtCurrentTable As DataTable = CType(ViewState("CurrentTable"), DataTable) Dim drCurrentRow As DataRow = dtCurrentTable.NewRow() drCurrentRow("RowNumber") = dtCurrentTable.Rows.Count + 1 drCurrentRow("SelectedKodItem") = String.Empty drCurrentRow("SelectedNoTagging") = String.Empty dtCurrentTable.Rows.Add(drCurrentRow) ViewState("CurrentTable") = dtCurrentTable Gridview1.DataSource = dtCurrentTable Gridview1.DataBind() Else Response.Write("ViewState is null") End If SetPreviousData() End Sub
5. 可选:保存ddlNoTagging的选中状态
如果需要持久化ddlNoTagging的选中值,添加事件处理:
Protected Sub ddlNoTagging_SelectedIndexChanged(sender As Object, e As EventArgs) Dim ddlNoTagging As DropDownList = CType(sender, DropDownList) Dim row As GridViewRow = CType(ddlNoTagging.NamingContainer, GridViewRow) If ViewState("CurrentTable") IsNot Nothing Then Dim dt As DataTable = CType(ViewState("CurrentTable"), DataTable) dt.Rows(row.RowIndex)("SelectedNoTagging") = ddlNoTagging.SelectedValue ViewState("CurrentTable") = dt End If End Sub
同时在前端给ddlNoTagging添加事件属性:
<asp:DropDownList ID="ddlNoTagging" runat="server" AppendDataBoundItems="True" class="form-control" DataSourceID="sqlListTagging" DataTextField="NoTagging" DataValueField="IDItem" AutoPostBack="True" OnSelectedIndexChanged="ddlNoTagging_SelectedIndexChanged"> </asp:DropDownList>
关键说明
- 所有用户选择的状态必须持久化到ViewState的DataTable中,GridView重新绑定后才能从这里恢复
- 依赖SqlDataSource自动绑定下拉框,避免手动重复绑定导致的状态丢失
- 恢复状态时先处理
ddlItem,再联动刷新ddlNoTagging,确保联动逻辑正确
内容的提问来源于stack exchange,提问作者Nurul Shahida
相关产品推荐
相关产品推荐

