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

C#中无法获取ASPxGridView内下拉框选中项数据求助

解决ASPxGridView中客户端绑定下拉框无法获取选中值的问题

这个问题我之前也碰到过,核心原因很明确:你通过WebMethod在客户端异步绑定的DropDownList,服务器端并没有维护它的视图状态和数据状态。因为所有选项都是在浏览器里加载的,服务器端控件的DataSource、Items集合在回发时是空的,自然就获取不到选中值,甚至会出现NullReferenceException。

下面给你两种针对性的解决方案,根据你的需求选择:

方案一:改用服务器端绑定(推荐,最稳定)

如果你的数据源可以在服务器端直接获取,建议把下拉框的绑定逻辑移到服务器端的GridView事件里,这样服务器能跟踪控件的状态,回发时就能正常读取选中值。

步骤1:给GridView添加OnInitNewRow事件

修改你的ASPX代码,给dgDepots加上初始化新行的事件:

<dx:ASPxGridView ID="dgDepots" runat="server" ClientInstanceName="grid" Width="100%" 
    OnRowDeleting="dgDepots_RowDeleting" 
    OnRowInserting="dgDepots_RowInserting" 
    OnRowUpdating="dgDepots_RowUpdating"
    OnInitNewRow="dgDepots_InitNewRow">
    <Columns>
        <dx:GridViewDataColumn FieldName="LocationCode" VisibleIndex="0">
            <EditItemTemplate>
                <asp:DropDownList ID="ddlLocation" runat="server"></asp:DropDownList>
            </EditItemTemplate>
        </dx:GridViewDataColumn>
    </Columns>
</dx:ASPxGridView>

步骤2:在服务器端实现绑定逻辑

在后台代码里,通过OnInitNewRow事件找到下拉框,用服务器端方式绑定数据:

protected void dgDepots_InitNewRow(object sender, DevExpress.Web.Data.ASPxDataInitNewRowEventArgs e)
{
    // 获取编辑行中的DropDownList控件
    var ddlLocation = (DropDownList)dgDepots.FindEditRowCellTemplateControl(
        (GridViewDataColumn)dgDepots.Columns["LocationCode"], 
        "ddlLocation"
    );

    // 这里替换成你原本在WebMethod里获取数据的逻辑(比如从数据库读取)
    var locationData = GetLocationCodesFromDatabase(); // 自定义方法,返回数据源
    ddlLocation.DataSource = locationData;
    ddlLocation.DataTextField = "Text"; // 对应你数据里的显示字段
    ddlLocation.DataValueField = "Value"; // 对应你数据里的取值字段
    ddlLocation.DataBind();

    // 添加默认选项
    ddlLocation.Items.Insert(0, new ListItem("Select", "-1"));
}

// 示例:模拟从数据库获取数据的方法
private DataTable GetLocationCodesFromDatabase()
{
    // 这里写你的数据库查询逻辑,返回包含Text和Value的DataTable
    DataTable dt = new DataTable();
    dt.Columns.Add("Text");
    dt.Columns.Add("Value");
    // 假设这是从数据库拿到的数据
    dt.Rows.Add("Location A", "1");
    dt.Rows.Add("Location B", "2");
    return dt;
}

步骤3:修改RowInserting事件获取值

现在你原来的RowInserting代码就能正常工作了,因为服务器端已经维护了下拉框的状态:

protected void dgDepots_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e)
{
    e.Cancel = true; // 取消GridView默认的插入逻辑,我们自己处理

    var ddlLocation = (DropDownList)dgDepots.FindEditRowCellTemplateControl(
        (GridViewDataColumn)dgDepots.Columns["LocationCode"], 
        "ddlLocation"
    );

    // 验证是否选择了有效选项
    if (ddlLocation.SelectedIndex > 0 && !string.IsNullOrEmpty(ddlLocation.SelectedValue))
    {
        using (var con = new SqlConnection("你的连接字符串"))
        {
            SqlCommand cmd = new SqlCommand("SP_Insert_Line_Item", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@LocationCode", ddlLocation.SelectedValue);
            
            con.Open();
            int i = cmd.ExecuteNonQuery();
            con.Close();
        }

        // 重新绑定GridView,刷新数据
        dgDepots.DataBind();
    }
}

方案二:保留客户端绑定,通过隐藏域传递值

如果必须用WebMethod客户端绑定,那可以通过隐藏域在客户端把选中值存起来,回发时服务器端读取隐藏域的值。

步骤1:在EditItemTemplate里添加隐藏域

修改ASPX的编辑模板,增加一个隐藏域:

<EditItemTemplate>
    <asp:DropDownList ID="ddlLocation" runat="server" OnClientSelectedIndexChanged="ddlLocation_OnSelectedIndexChanged"></asp:DropDownList>
    <asp:HiddenField ID="hfSelectedLocation" runat="server" />
</EditItemTemplate>

步骤2:写客户端脚本同步选中值到隐藏域

在页面里添加JavaScript,当下拉框选中项变化时,把值存到隐藏域:

function ddlLocation_OnSelectedIndexChanged(sender, args) {
    // 获取隐藏域的客户端ID,赋值选中值
    var hiddenField = document.getElementById('<%= hfSelectedLocation.ClientID %>');
    hiddenField.value = sender.value;
}

步骤3:在RowInserting事件里读取隐藏域的值

后台代码里不再直接操作DropDownList,而是读取隐藏域的值:

protected void dgDepots_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e)
{
    e.Cancel = true;

    // 获取隐藏域控件
    var hfLocation = (HiddenField)dgDepots.FindEditRowCellTemplateControl(
        (GridViewDataColumn)dgDepots.Columns["LocationCode"], 
        "hfSelectedLocation"
    );

    string selectedValue = hfLocation.Value;
    if (!string.IsNullOrEmpty(selectedValue) && selectedValue != "Select")
    {
        using (var con = new SqlConnection("你的连接字符串"))
        {
            SqlCommand cmd = new SqlCommand("SP_Insert_Line_Item", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@LocationCode", selectedValue);
            
            con.Open();
            int i = cmd.ExecuteNonQuery();
            con.Close();
        }

        dgDepots.DataBind();
    }
}

补充说明

你提到的ContentPlaceHolder不会影响这个问题,核心矛盾就是客户端绑定的控件服务器端无状态——服务器端不知道你在客户端加载了哪些选项,所以回发时控件的状态是“空”的,自然拿不到选中值。

内容的提问来源于stack exchange,提问作者sa f

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:12:44