You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridView内嵌DropDownList回发后首次选值丢失问题求助

解决GridView中DropDownList首次选择回发后重置的问题

看起来你遇到的问题是GridView编辑行里的DropDownList第一次选值后,回发就变回初始状态,第二次才正常保留。这其实是ASP.NET WebForms里很常见的视图状态与事件生命周期冲突问题,我来帮你拆解解决:

问题根源

每次DropDownList触发AutoPostBack回发时,你的GridView2_ddl(也就是RowDataBound事件)会重新执行。之前的代码里,你每次都会重新绑定DropDownList数据,还强制把SelectedValue设为数据源的原始ID——但回发时GridView并没有重新绑定数据源,e.Row.DataItem实际上是null,这就导致你要么设置了错误值,要么直接覆盖了用户刚选的结果。第一次回发被重置,第二次因为编辑状态持续且没有再强制覆盖,才看起来正常。

解决方案

我们需要修改代码,区分「首次进入编辑模式」和「回发后的编辑状态」,确保回发时保留用户选择的值:

1. 补充GridView的正确绑定逻辑

你原来的Page_Load里只绑定了空DataTable,这肯定不对,先补充一个绑定GridView数据源的方法:

private void BindGridView2()
{
    string constr = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        // 替换成你实际获取GridView数据的SQL语句
        using (SqlCommand cmd = new SqlCommand("SELECT ID, MonitorDetailsID FROM YourActualTableName"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
            {
                DataTable dt = new DataTable();
                sda.Fill(dt);
                GridView2.DataSource = dt;
                GridView2.DataBind();
            }
        }
    }
}

然后修改Page_Load,调用这个方法加载数据:

protected void Page_Load(object sender, EventArgs e)
{
    IntranetCore masterpage = (IntranetCore)(Page.Master);
    masterpage.PageTitle = "Maintain Database Tables";
    masterpage.ShowPageLastUpdated = false;
    Master.Page.Title = "test";
    this.Title = "Maintain Database Tables";
    
    if (!IsPostBack)
    {
        BindGridView2(); // 首次加载时绑定实际数据源
    }
}

2. 处理RowEditing事件,保存原始ID

当用户进入编辑模式时,把当前行的原始MonitorDetailsID保存到ViewState,方便后续判断:

protected void GridView2_RowEditing(object sender, GridViewEditEventArgs e)
{
    GridView2.EditIndex = e.NewEditIndex;
    // 获取当前行的原始MonitorDetailsID并保存到ViewState
    int originalID = Convert.ToInt32(GridView2.DataKeys[e.NewEditIndex].Values["MonitorDetailsID"]);
    ViewState["OriginalMonitorDetailsID"] = originalID;
    // 重新绑定GridView,确保编辑状态正确显示
    BindGridView2();
}

3. 修改RowDataBound事件,正确设置选中值

修改你的GridView2_ddl方法,回发时优先使用用户选择的值,而不是强制设置原始值:

protected void GridView2_ddl(object sender, GridViewRowEventArgs e)
{
    if ((e.Row.RowState & DataControlRowState.Edit) > 0)
    {
        string constr = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
        using (SqlConnection con = new SqlConnection(constr))
        {
            using (SqlCommand cmd = new SqlCommand(@"select top 100 ID, name from db_monitordetails;"))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.Connection = con;
                    sda.SelectCommand = cmd;
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);
                        DropDownList ddl = (DropDownList)e.Row.FindControl("txtMonitorDetailsID1");
                        
                        ddl.DataSource = dt;
                        ddl.DataValueField = "ID";
                        ddl.DataTextField = "name";
                        ddl.AppendDataBoundItems = true;
                        ddl.Items.Clear(); // 先清空,避免重复添加默认项
                        ddl.Items.Insert(0, new ListItem("--Select Monitor details--", "0"));
                        ddl.DataBind();

                        string selectedValue = null;
                        // 回发时,从Request中获取用户实际选择的值
                        if (IsPostBack)
                        {
                            string ddlClientID = ddl.ClientID;
                            selectedValue = Request.Form[ddlClientID];
                        }
                        
                        // 如果没有回发值,用原始的ID
                        if (string.IsNullOrEmpty(selectedValue))
                        {
                            selectedValue = ViewState["OriginalMonitorDetailsID"]?.ToString();
                        }

                        // 确保选中值存在,再设置
                        if (!string.IsNullOrEmpty(selectedValue) && ddl.Items.FindByValue(selectedValue) != null)
                        {
                            ddl.SelectedValue = selectedValue;
                        }
                    }
                }
            }
        }
    }
}

4. 修正GridView的DataKeyNames

你原来的GridView只把ID设为DataKeyNames,需要加上MonitorDetailsID,这样才能在RowEditing里获取到原始值:

<asp:GridView runat="server" ID="GridView2" Width="100%" AutoGenerateColumns="False" ShowFooter="True" 
    DataKeyNames="ID,MonitorDetailsID" 
    OnPageIndexChanging="GridView2_PageIndexChanging" OnRowDeleting="GridView2_RowDeleting" 
    OnRowEditing="GridView2_RowEditing" OnRowUpdating="GridView2_RowUpdating" 
    OnRowCancelingEdit="GridView2_RowCancelingEdit" OnRowCommand="GridView2_RowCommand" 
    HeaderStyle-CssClass="GVFixedHeader" FooterStyle-CssClass="GVFixedFooter" 
    OnRowDataBound="GridView2_ddl" EnableViewState="true" >
    <!-- 其他列代码不变 -->
</asp:GridView>

这样修改后,第一次选择DropDownList的值回发时,就能正确保留用户选择的结果了。

内容的提问来源于stack exchange,提问作者Aarthi Muthusami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:48:52