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

C# Ext.Net动态添加到FieldSet的NumberField无法获取值求助

解决动态添加NumberField后无法获取值的问题

我之前也碰到过一模一样的情况,这其实是Asp.net WebForms结合Ext.NET Direct Method时的控件生命周期坑点——动态添加的控件不会在回发时自动保留在服务器端的控件树里,所以你后续访问PerVisitFS.Items.Count()才会是0。下面给你具体的解决思路和代码示例:

核心原因

Direct Method是异步执行的,执行完动态添加控件后,这些控件只存在于当前的页面响应中。当你后续触发回发(比如另一个Direct Method或者按钮提交)时,服务器端的控件树会重新初始化,之前动态添加的控件不会自动重建,自然就找不到它们和用户输入的值了。

解决方案:手动重建动态控件

要解决这个问题,你需要:

  1. 把动态控件的关键元数据(比如每个Visit的名称)保存到ViewState或Session中,确保回发后能拿到这些信息。
  2. 在页面生命周期的早期阶段(比如Page_Init),用保存的元数据重新创建所有动态控件,并且保证控件的ID和第一次创建时完全一致——这样Asp.net才能通过ViewState恢复用户输入的值。

步骤1:修改Direct Method,保存元数据

[DirectMethod]
public void LoadVisitFields(int tid)
{
    var visits = from v in dc.Visits where v.tid == tid select v;
    
    // 保存需要重建控件的元数据到ViewState
    List<string> visitNames = visits.Select(v => v.VISITName).ToList();
    ViewState["VisitNames"] = visitNames;

    // 第一次动态添加控件
    foreach (var v in visits)
    {
        NumberField nf = new NumberField();
        nf.ID = v.VISITName + "num";
        nf.MaxValue = 100;
        nf.MinValue = 0;
        nf.FieldLabel = v.VISITName;
        PerVisitFS.Items.Add(nf);
        nf.Render();
    }
}

步骤2:在Page_Init中重建控件

在页面的Page_Init事件里,读取保存的元数据,重新创建并添加所有NumberField:

protected void Page_Init(object sender, EventArgs e)
{
    // 只有当ViewState里有保存的元数据时才重建
    if (ViewState["VisitNames"] != null)
    {
        List<string> visitNames = (List<string>)ViewState["VisitNames"];
        foreach (string name in visitNames)
        {
            NumberField nf = new NumberField();
            nf.ID = name + "num"; // ID必须和第一次创建时完全一致
            nf.MaxValue = 100;
            nf.MinValue = 0;
            nf.FieldLabel = name;
            PerVisitFS.Items.Add(nf);
        }
    }
}

步骤3:正常获取控件值

现在当你需要获取用户输入的值时,PerVisitFS.Items里就会包含所有动态添加的NumberField了,直接遍历或者通过ID查找即可:

[DirectMethod]
public void GetUserInputValues()
{
    foreach (var item in PerVisitFS.Items)
    {
        if (item is NumberField numberField)
        {
            decimal? inputValue = numberField.Value;
            // 这里处理拿到的输入值,比如保存到数据库
        }
    }

    // 或者通过ID精准查找
    // NumberField specificField = PerVisitFS.FindControl("某个VISITName" + "num") as NumberField;
    // if (specificField != null) { /* 处理值 */ }
}

注意事项

  • 一定要在Page_Init阶段重建控件,这个阶段在ViewState加载之前,能保证控件正确绑定用户输入的值。如果放在Page_Load里,可能会导致ViewState无法正确恢复。
  • 控件的ID必须完全一致,Asp.net是通过ID来匹配ViewState中的值的,ID不一样就找不到对应的输入值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:43:03