使用LoadControl在Load事件中的陷阱

5
我在Load事件中广泛使用LoadControl方法。然而,我还没有观察到任何问题,但我担心MSDN文档所说的:
当您将控件加载到容器控件中时,容器会引发所有已添加控件的事件,直到它追上当前事件为止。然而,添加的控件不会赶上回发数据处理。为了使添加的控件参与回发数据处理(包括验证),必须在Init事件中添加控件,而不是在Load事件中添加。
这实际上是什么意思?
在Load事件中加载控件还有其他问题吗?

1
ViewState应该不会出现问题,即使在load事件之前加载。这是由以下内容覆盖的:"raises all of the added control's events until it has caught up to the current event"。 但我认为在您的UserControl中引发自定义事件可能会出现问题。请检查一下。 - Tim Schmelter
我可以问一下为什么你需要使用页面的加载事件吗?顺便说一句,在加载期间添加控件时,无法检测到自定义事件的问题。 - Tim Schmelter
表单数据不会在 Init 事件中加载到控件中。直接访问 HttpContext.Current.Request.Form 有点不方便。使用自定义事件的优点很好,我会去检查一下。 - Jakub Linhart
有一个可能会让你困惑的地方是添加控件到控件树的顺序以及在该控件上设置属性 - 这与ViewState有关。如果您在将控件添加到控件树之前设置控件的属性,则您设置的属性(例如Text属性)不会被添加到ViewState中。但是,如果您在将其添加到控件树后设置属性,则它会被添加到ViewState中。 - dice
2个回答

4
那部分MSDN文档(大部分)是错误的。正如你所发现的,即使在“Load”事件中动态添加控件,后退数据处理和验证也可以工作。
以下是与此问题相关的ASP.NET页面生命周期阶段:
1.引发“Init”事件。 2.后退:装载视图状态和控制状态。 3.后退:装载已发布的表单数据(第一次尝试)。 4.引发“Load”事件。 5.后退:装载已发布的表单数据(第二次尝试)。 6.后退:验证表单并引发后退事件。
当文档说“添加的控件没有赶上后退数据处理”时,它是正确的。但它忽略了这个事实,即有两个尝试来加载已发布的表单数据,一个在“Load”事件之前,一个在之后。因此,如果您在“Load”事件中动态添加控件,则该控件将在后退事件(例如“submitButton_Click”)发生时被填充已发布的表单数据。
据我所知,以下是主要区别和潜在陷阱:
1.如果您在“Init”中动态添加控件,则可以在“Load”中访问其已发布的表单数据。 2.如果您在“Load”中动态添加控件,则必须等到后退事件(否则直接访问“HttpRequest.Form”集合)。

1
非常有见地的回答。所描述的“潜在”陷阱非常危险。我还没有遇到过任何困难的问题,因为我很幸运。谢谢。 - Jakub Linhart

1

这意味着在执行Control_Load时,PostBack周期已经结束。如果您有一个需要参与PostBack的控件,则需要在之前加载它,这就是为什么文档建议在Init重写中执行。

如果您的控件不参与PostBack,那么就没问题了。


如果您不打算在服务器上使用它,为什么要创建一个服务器端的UserControl?除此之外,在page_load中postback-cycle尚未完成,但是例如viewstate已经加载。 - Tim Schmelter
OP并没有谈论ViewState,一旦它被加载,它就始终可用。他所提到的段落涉及_postback_操作。 - kprobst
ViewStatepostback 数据处理 的一部分。实际上,OP 想要知道在页面的加载事件期间动态添加控件时有哪些潜在问题。"不参与 postback" 是什么意思?即使在 page_load 中添加了 UserControl,您也可以读取或写入其属性并处理其事件。控件的 ViewState/ControlState 不是问题,因为页面确保所有控件的事件都被触发,直到它赶上当前事件(包括加载 ViewState)。 - Tim Schmelter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接