3

我有一个 ASP.NET Web 表单复合控件,我们称它为控件 A,其中包含一个子复合控件,我将其称为控件 B。控件 B 的子控件依赖于控件 A 的属性。

在初始加载时,我在控件 A 的 OnLoad 中设置此参数,并且控件 B 在 CreateChildControls 中正确设置其子控件时一切正常。

但是,当我想通过控件 A 的下拉列表中的 SelectedIndexChanged 更改此参数时,事件处理程序似乎在生命周期中处理得太晚,控件 B 无法获取更改的值。想必这是因为控件 B 的 CreateChildControls 方法已经被调用了。

如何让控件 B 以这样的方式更新其子控件,以便它们可以通过正常的生命周期,根据需要加载视图状态?

只是为了清楚起见,当控件 A 的参数发生更改时,控件 B 的子控件可能必须保留一些,一些需要删除,一些需要添加,因此对于保留的那些,它们仍然需要负载状态。

4

1 回答 1

4

SelectedIndexChanged 事件将在页面和控件 A 的 Page_Load (OnLoad) 之后处理。并且您认为您的页面已经重建并且视图状态在您到达此事件处理程序时恢复到控件是正确的 - 因为它应该是,当页面/控件尚未重建时处理事件有什么意义?

我建议的三个简单的解决方案是:

  • 没有控件 B 检查其父级的值,然后相应地构建自己,这有点反模式。相反,让控件 A 根据下拉列表的值加载正确版本的控件 B。IOW 让控件 A 负责加载什么,而不是控件 B。控件 B 应该是愚蠢的,而不关心它的父对象是什么。如果它需要与其父级接口,它应该通过接口来完成。

  • 如果您只是隐藏和显示字段,则只需将它们全部放在控件 B 中,并隐藏不应显示的字段。如果您将其可见属性设置为 false,大多数控件将不会将任何 HTML 呈现到输出流,因此当页面被发送回客户端时对客户端的影响最小

  • 控制 A 根据所选值重建自身的部分。它可以包含一个 DIV,您执行 div.Controls.Clear(),然后将正确的控件添加回其中。这可以在 SelectedIndexChanged 事件中执行,因为您不关心已经存在哪些控件以及它们的值是什么(如果您确实关心某些现有控件,那么从控件集合并在它们周围添加新控件)

这三种方法中的每一种都有其优点和缺点,你最终可能会做的是这三种方法的混合。还有另一种可能的方法,您可以利用 PageParser 及其 GetCompiledPageInstance 方法来获取用于重新生成页面的 IHttpHandler,但这是一种高级方法,可以在这里用一个小回复来介绍。

于 2009-12-06T11:10:37.797 回答