其中一個缺陷是,如果該控件未包含在<form>
中,它將不存在。我建議繼續並在事件處理程序階段添加它們 - 因爲那時您知道要添加的內容 - 但存儲必要的信息以重建ViewState
或SessionState
中的那些控件。
通過這樣做,您將能夠在OnInit
中重新創建它們,但不必處理現在正在走向的道路周圍的一些其他複雜性。
因此,假設您發現您需要構建控件。你會建立它:
var tb = new TextBox();
tb.ID = "myTextBox";
...
,但你也想保存必要的狀態信息:
this.ViewState.StoreControl(typeof(TextBox), "myTextBox");
,然後就建立擴展方法:
public static void StoreControl(this StateBag vs, Type controlType, string name)
{
var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls == null)
{
dynamicControls = new List<Tuple<Type, string>>();
vs["DynamicControls"] = dynamicControls;
}
var t = dynamicControls.FirstOrDefault(tp => tp.Item2 == name);
if (t == null) { dynamicControls.Add(Tuple.Create(controlType, name)); }
}
然後OnInit
你可能會這樣做:
var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls != null)
{
foreach (var tp in dynamicControls)
{
Control c = Activator.CreateInstance(tp.Item1) as Control;
c.ID = tp.Item2;
this.Controls.Add(c);
}
}
注意:此代碼寫在SO上。它沒有被編譯或調試。但你明白了。
如何在asp.net服務器控件中不包含
@BlueChameleon,它可以完成,我已經完成了。我不是說它會成爲主流 - 我只是說它可以完成。但是,請參閱我的編輯。 –
老實說,我看到你在這裏做什麼,但你提到的原始陷阱在我們的系統中永遠不會發生,因爲如果我們開始在窗體外添加控件,我們不能使用Control.FindControl()來查找它們,這會破壞一切。再加上一堆標準的ASP.NET控件調用System.Web.UI.Page.VerifyRenderingInServerForm()來確保它們在表單中,否則它們會引發錯誤。 – BlueChameleon