C# Ext.Net动态添加到FieldSet的NumberField无法获取值求助
解决动态添加NumberField后无法获取值的问题
我之前也碰到过一模一样的情况,这其实是Asp.net WebForms结合Ext.NET Direct Method时的控件生命周期坑点——动态添加的控件不会在回发时自动保留在服务器端的控件树里,所以你后续访问PerVisitFS.Items.Count()才会是0。下面给你具体的解决思路和代码示例:
核心原因
Direct Method是异步执行的,执行完动态添加控件后,这些控件只存在于当前的页面响应中。当你后续触发回发(比如另一个Direct Method或者按钮提交)时,服务器端的控件树会重新初始化,之前动态添加的控件不会自动重建,自然就找不到它们和用户输入的值了。
解决方案:手动重建动态控件
要解决这个问题,你需要:
- 把动态控件的关键元数据(比如每个Visit的名称)保存到
ViewState或Session中,确保回发后能拿到这些信息。 - 在页面生命周期的早期阶段(比如
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
相关产品推荐
相关产品推荐

