好的,我试图了解如何最好地处理ViewState
,以便使用C#对默认值进行编程设置。我了解ViewState
隐藏字段的构造基于触发OnInit
事件后设置的每个值。我不清楚的是,使用控件的构造函数或OnInit
事件设置默认值之间是否有区别。
public MyControl(){
this.Text = "SomeDefaultValue";
}
与
protected override void OnInit(EventArgs e){
this.Text = "SomeDefaultValue";
}
我见过一些建议在给定属性的
null
中测试get
的ViewState值的地方,例如:public string Text {
get {
return this.ViewState["Text"] == null ?
"SomeDefaultValue" :
this.ViewState["Text"] as string;
}
set { this.ViewState["Text"] = value; }
}
我不喜欢这样做,因为这样会使清除值变得混乱。
那么,使用构造函数与
OnInit
设置默认ViewState
值之间在功能上有什么区别吗? 最佳答案
就最小化ViewState而言,没有区别,因为ViewState在运行OnInit
方法之后开始跟踪。
但是,存在一些功能上的差异:在控件初始化之前,您无法访问Page
之类的其他属性。因此,我通常更喜欢使用OnInit
或绑定到Init
事件的某些处理程序。
另外,在重写OnInit时要格外小心:您应调用base.OnInit()
以确保仍调用Init事件的其他事件处理程序。
我强烈建议您阅读有关以下主题的出色文章:http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
编辑
为了明确起见,在为该控件运行OnInit
方法之后,ViewState开始跟踪该控件。因此,在给定的示例中,可以安全地覆盖OnInit
,如下所示:
protected override void OnInit(EventArgs e){
this.Text = "SomeDefaultValue"; // Make sure this happens before base.OnInit
base.OnInit();
}
之所以起作用,是因为
Text
属性将值保存到此控件的ViewState中。但是,假设您还有另一个子控件(我将使用Label
作为示例)。在调用控件的OnInit
方法时,该Label的OnInit
已经运行。因此,如果要更改Label的Text值,则需要在该标签的OnInit阶段(或更早)进行此操作。您可以在当前控件的构造函数中执行此操作:
public MyControl(){
this.Label.Text = "SomeDefaultValue";
}
...但是如前所述,您将无权访问外部控制结构,在某些情况下这可能是必需的。在这些情况下,一个不错的选择是在标签本身上使用
Init
事件处理程序。您可以将事件处理程序本身连接到构造函数中:public MyControl(){
this.Label.Init +=
(sender, e) => this.Label.Text =
((TextBox)Page.FindControl("SomeControl")).Text;
}
...,但这仅在控件直接声明为类的成员时才有效。如果标签在模板内(例如在Repeater中),则需要使用标记将其连接起来:
<asp:Label runat="server" OnInit="Label_Init" />
后面的代码:
public void Label_Init(object sender, EventArgs e)
{
var label = (Label)sender;
label.Text = ((TextBox)Page.FindControl("SomeControl")).Text;
}
后一个示例的优点是可以在我能想到的几乎每种情况下工作,但它需要更多样板代码以及标记的更改。因此,请根据您的具体情况选择毒药。
关于c# - 最小化ASP.Net中的ViewState大小,在构造函数和OnInit中初始化控件值之间有区别吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5638875/