如何在回发时更改复合服务器控件中的子控件

发布于 2024-08-13 14:18:26 字数 435 浏览 6 评论 0原文

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

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

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

如何让控件 B 更新其子控件,以便它们可以完成正常的生命周期,并根据需要加载视图状态?

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

I have an ASP.NET web form composite control, let's call it control A, which contains a child composite control, which I'll call control B. The child controls of control B are dependent on a property of control A.

On initial load I am setting this parameter in OnLoad of control A and everything works fine with the control B setting up its child controls correctly in CreateChildControls.

However, when I want to change this parameter via SelectedIndexChanged on a dropdown in control A the event handler seems to be handled too late in the lifecycle for control B to pick up the changed value. Presumably this is because the CreateChildControls method of control B has already been called.

How can I get control B to update its child controls in such a way that they can then go through their normal lifecycle, loading viewstate as necessary?

Just for clarity, when the parameter of control A is changed the child controls of control B may have to have some that remain, some that need to be removed and some that need to be added, hence for the ones that remain they still need to load state.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

や三分注定 2024-08-20 14:18:26

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

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

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

  • 如果您只是隐藏和显示字段,那么只需将它们全部放在控件 B 中,并隐藏不应该显示的字段。 当页面发送回客户端时,对客户端的影响最小

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

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

The SelectedIndexChanged event will be handled after the Page_Load (OnLoad) of the page and control A. And you are right in thinking that your page is already rebuilt and viewstate reinstated back to controls by the time you get to this event handler - as it should be, what is the point of handling events when the page/control has not been rebuilt yet?

The three easy solutions i would suggest for this are:

  • don't have control B check its parent for a value and then build itself accordingly, this is a bit of an anti-pattern. Instead, have control A load the right version of control B depending on the value of the dropdown. IOW make control A responsible for what is loaded, not control B. Control B should be dumb and not care what its parent is. If it needs to interface to its parent it should do it through an interface.

  • if you are only hiding and showing fields, then just have them all in control B, and hide the ones that should not be shown. Most controls will not render any HTML to the output stream if you set their visible property to false, so there is minimal impact on the client side when the page gets sent back to the client

  • have control A rebuild portions of itself depending on the selected value. It could contain a DIV, you do a div.Controls.Clear(), and then add the right controls back in to it. This will be fine to do in the SelectedIndexChanged event, as you don't care what controls are already there and what their values are (if you do care about some of the existing controls, then it is relatively trivial to not clear those from the control collection and to add the new controls around them)

Each of these three methods has it's pros and cons, and what you may end up doing is a mixture of the three. There is also another possible method where you utilise the PageParser and its GetCompiledPageInstance method to get an IHttpHandler that you use to regenerate the page, but that is way to advanced to cover with a small reply here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文