由于 UniqueID 更改,post 后动态控件中文本框的文本未设置
The text of a textbox in a dynamic control is not set on post back due to UniqueID change
如标题所示,我们在 post 返回后获取文本框的正确文本值时遇到问题。
上下文:
- 文本框名为
textbox_registration
- 文本框位于动态加载的控件中。
- 动态控件每隔 post 重新创建一次,并在 OnInit 事件中设置其数据。
- 动态控件位于 UpdatePanel 内的 PlaceHolder 中。
预计表单中输入的值 post 将出现在文本框的 Text
属性 中。第一次提交表单很好,然后就变得奇怪了。 textbox_registration
的 UniqueID 在每次后续提交中都会发生变化,从而打破了存储在 Text
属性 中的预期值。以下是文本框的 UniqueID 示例。
ctl00$CollapsableSidebar$panel_editAsset$ctl01$textbox_registration
ctl00$CollapsableSidebar$panel_editAsset$ctl02$textbox_registration
我的理论是,当它再次在 init 中加载动态控件时,它通过更改生成的 UniqueID 避免与前一个文本框实例发生冲突,然后当第二个 post 返回时,ID 必须不同,从而破坏 init 和 load 方法之间的 ViewState 初始化。
这非常令人恼火,因为查看 Request.Form collection 我可以看到正确的 posted 值。
如何检索 textbox_registration.Text
的 posted 值?
编辑 1:
只是为了澄清 textbox_registration 是我们动态加载的 UserControl 中的普通静态 ASP 文本框。
编辑 2:
为了概述场景,源代码已被简化为以下文件:
- Item Page,显示项目的页面。
- Edit Pane,用于加载动态控件的项目页面上的自定义 UserControl。
- Dynamic Control,加载到编辑窗格中的动态项目编辑控件示例。
- IEditItemPanel,编辑控件必须实现的接口。
尝试在创建 TextBox 控件时设置 ClientIDMode
属性
textbox_registration.ClientIDMode = ClientIDMode.Static;
然后当你想检索文本时
var textBox = (TextBox)this.Form.FindControl("textbox_registration");
var textBoxText = textBox.Text;
调查问题后,这是一个逻辑错误导致的问题。
因为编辑控件是动态加载的,所以只要项目是在调用 Controls.Add()
之前加载到控件中。
有了这些知识,OnInit
事件在动态控制中得到了仔细调查。 在 post 的背上被称为 两次!逻辑错误!这导致控件被创建两次,并且 posted 表单值对应于在第一次 OnInit
调用中创建的控件。因此,第二个 OnInit
调用为控件生成了不同的 UniqueID。恢复 ViewState 时,控件不存在。
解决方案是确保每次 post 都正确创建控件,就像第一次创建控件一样。第一次没有做重复控件,所以第二次也不应该!
原来需要回顾一下 'Dynamic Controls Basics 101'。
这个 link 'Dynamic Controls Made Easy in ASP.Net' 终于让解决方案成为焦点。
如标题所示,我们在 post 返回后获取文本框的正确文本值时遇到问题。
上下文:
- 文本框名为
textbox_registration
- 文本框位于动态加载的控件中。
- 动态控件每隔 post 重新创建一次,并在 OnInit 事件中设置其数据。
- 动态控件位于 UpdatePanel 内的 PlaceHolder 中。
预计表单中输入的值 post 将出现在文本框的 Text
属性 中。第一次提交表单很好,然后就变得奇怪了。 textbox_registration
的 UniqueID 在每次后续提交中都会发生变化,从而打破了存储在 Text
属性 中的预期值。以下是文本框的 UniqueID 示例。
ctl00$CollapsableSidebar$panel_editAsset$ctl01$textbox_registration ctl00$CollapsableSidebar$panel_editAsset$ctl02$textbox_registration
我的理论是,当它再次在 init 中加载动态控件时,它通过更改生成的 UniqueID 避免与前一个文本框实例发生冲突,然后当第二个 post 返回时,ID 必须不同,从而破坏 init 和 load 方法之间的 ViewState 初始化。
这非常令人恼火,因为查看 Request.Form collection 我可以看到正确的 posted 值。
如何检索 textbox_registration.Text
的 posted 值?
编辑 1: 只是为了澄清 textbox_registration 是我们动态加载的 UserControl 中的普通静态 ASP 文本框。
编辑 2: 为了概述场景,源代码已被简化为以下文件:
- Item Page,显示项目的页面。
- Edit Pane,用于加载动态控件的项目页面上的自定义 UserControl。
- Dynamic Control,加载到编辑窗格中的动态项目编辑控件示例。
- IEditItemPanel,编辑控件必须实现的接口。
尝试在创建 TextBox 控件时设置 ClientIDMode
属性
textbox_registration.ClientIDMode = ClientIDMode.Static;
然后当你想检索文本时
var textBox = (TextBox)this.Form.FindControl("textbox_registration");
var textBoxText = textBox.Text;
调查问题后,这是一个逻辑错误导致的问题。
因为编辑控件是动态加载的,所以只要项目是在调用 Controls.Add()
之前加载到控件中。
有了这些知识,OnInit
事件在动态控制中得到了仔细调查。 在 post 的背上被称为 两次!逻辑错误!这导致控件被创建两次,并且 posted 表单值对应于在第一次 OnInit
调用中创建的控件。因此,第二个 OnInit
调用为控件生成了不同的 UniqueID。恢复 ViewState 时,控件不存在。
解决方案是确保每次 post 都正确创建控件,就像第一次创建控件一样。第一次没有做重复控件,所以第二次也不应该!
原来需要回顾一下 'Dynamic Controls Basics 101'。 这个 link 'Dynamic Controls Made Easy in ASP.Net' 终于让解决方案成为焦点。