2009-12-06 29 views
3

複合服務器控件我有一個ASP.NET web窗體複合控件,讓我們把它控制A,其中包含一個子複合控件,我稱之爲控制B.兒童控制B的控件取決於控件A的屬性。如何更改子控件在回發

在初始加載時,我在控件A的OnLoad中設置此參數,並且一切正常,控件B在CreateChildControls中正確設置其子控件。

但是,當我想通過控件A的下拉列表中的SelectedIndexChanged更改此參數時,事件處理程序似乎在控件B的生命週期中處理得太晚,無法獲取更改後的值。據推測這是因爲控件B的CreateChildControls方法已經被調用。

我怎樣才能得到控制B到更新其子控件以這樣的方式,他們可以再通過他們正常的生命週期內,根據需要加載視圖狀態?

只是爲了清楚起見,當控件A的參數發生變化時,控件B的子控件可能需要保留一些控件,有些需要刪除,有些需要添加,因此對於剩下的控件他們仍然需要加載狀態。

回答

4

SelectedIndexChanged事件將在頁面和控件A的Page_Load(OnLoad)之後處理。你認爲你的頁面已經被重建並且viewstate在你到達這個事件處理器時恢復到控件的狀態 - 因爲它應該是,當頁面/控件還沒有被重建時處理事件的要點是什麼?

三個簡單的解決方案,我建議這個是:

  • 沒有控制B查看其父的值,然後建立自身相應的,這是一個有點反模式。相反,讓控件A根據下拉的值加載控件B的正確版本。 IOW使控制A負責裝載什麼,而不是控制B.控制B應該是愚蠢的,而不在乎它的父母是什麼。如果需要連接到它的父級,它應該通過一個接口來完成。

  • 如果你只是隱藏和顯示字段,那麼只需讓他們全部在控制B中,並隱藏那些不應該顯示的。大多數控件將不會呈現任何HTML輸出流,如果你設置其可見屬性設置爲false,所以當網頁被髮送回客戶端

  • 有控制重建自身部分在客戶端的影響最小取決於所選的值。它可以包含一個DIV,你做一個div.Controls.Clear(),然後將正確的控件重新添加到它。這將是罰款SelectedIndexChanged事件做,因爲你不關心控件是什麼已經存在,它們的值是什麼(如果你做的一些現有控件的護理,那麼它是比較瑣碎不清除這些從控制採集和添加新的控件周圍)

這三種方法都有它的優點和缺點,你可能最終做的是三者的混合物。還有另一種可能的方法,即利用PageParser及其GetCompiledPageInstance方法來獲取用於重新生成頁面的IHttpHandler,但這是一種高級方式,可在此處用一個小小的回覆來覆蓋。

+0

關於您的第一個建議:由於值的更改發生在事件處理程序中,因此在調用CreateChildControls之後,控件b已經使用舊設置創建。你如何看待這個工作? – 2009-12-07 09:09:28

相關問題