2008-12-08 77 views
1

好的时候,以显示我完全缺乏知识的web表单的所有东西,但在这里。我扩展了Panel控件,并且OnPreRender在其中添加了一些额外的控件(为简单起见,我们只说1个文本框)。从这里我只是让面板渲染方法做它的事情。服务器控件和查看状态

我遇到的问题是,显然每次该控件被重新渲染时,它只是在面板中再次粘贴相同的TextBox,并在OnPreRender方法中编码值。现在我实际上并不想每次都重新填充面板,我想在第一次加载时将textbox控件粘贴在那里,并让它们从控件/视图状态缓存中重新加载。在这种情况下,我只是在面板中粘贴单个文本框的示例,如果文本框的值发生更改并发生回发,我希望该值保持更改后的值。

真的很基本的webforms我知道的东西,但我从来没有必须在我的时间创建自定义控件。任何帮助表示赞赏。

克里斯。

回答

3

您需要(重新)在OnInit中创建子控件(文本框) - 以便在调用LoadViewState和ProcessPostBackData时它在那里。

查看server control lifecycle了解更多信息。

+0

干杯,这是正确的。 – Owen 2008-12-08 17:00:07

0

在代码中,如果您需要viewstate服务,您将需要管理视图状态信息的还原。

这里的一个很好的例子是微软的View State example。代码示例中引用了一些其他项目,但它应该可以帮助您沿着正确的道路前进。

1

ASP.NET中的动态控件非常棘手,尤其是如果您对webforms和页面生命周期不熟悉的话。如果你可以避免动态控制,那就这样做。改用controlName.Visible = false和其他技巧。如果您必须阅读this article。经验法则,在页面生命周期的早期添加控件,稍后在页面生命周期中引用它们。 PreRender几乎是最终目标,这是一个不常见的添加和使用控件的地方。

1

不知道这是否适用于.Net(我认为2.0或更高版本)的所有版本,但有一个名为CreateChildControls的方法并不完全是生命周期的一部分,它基本上在EnsureChildControls方法是调用。默认情况下,它在PreRender之前调用,如果它不是回发。所以基本上你的代码应该是这样的:

public class SomeControl : WebControl, INamingContainer 
{ 
    private TextBox someTextBox; 

    protected override void CreateChildControls() 
    { 
    base.CreateChildControls(); 

    someTextBox= new TextBox(); 
    someTextBox.ID = "tbxMain"; 

    Controls.Add(textboxToCheck); 
    } 
} 

现在部分不是,除非你叫EnsureChildControls,你不能100%地肯定存在的控件之前对你控制的公共属性被填满ViewState加载。这是什么意思?那么把代码前加一个属性CssClass属性:

public class SomeControl : WebControl, INamingContainer 
{ 
    private TextBox someTextBox; 

    protected override void CreateChildControls() 
    { 
    base.CreateChildControls(); 

    someTextBox= new TextBox(); 
    someTextBox.ID = "tbxMain"; 

    Controls.Add(textboxToCheck); 
    } 

    public String CssClass { get; set; } 
} 

在CreateChildControls中,你不会想这样的:

someTextBox.CssClass = CssClass; 

因为没有办法,以确保控制还不存在。还有,你可以处理这几种方法:

公共字符串的CssClass { 得到 { EnsureChildControls(); return someTextbox.CssClass; }

set 
{ 
    EnsureChildControls(); 
    someTextbox.CssClass = value; 
} 

在这个例子中我打电话EnsureChildControls(假设您正在设置CssValue在CreateChildControls方法的文本框),并设置或文本框获得。

另一种方法是把任何东西在的OnPreRender方法取决于控制的公共属性:

protected override void OnPreRender(EventArgs e) 
{ 
    someTextbox.CssClass = CssClass; 
} 

从而避免担心财产被ViewState的负载时已填写的混乱。

一注:

使用作INamingContainer的也很重要。基本上,所有这些都确保父控件上的控件具有一个在页面上唯一的id,方法是将父项的名称(也许更多)应用于id。基本上,如果父ID是Parent,并且子控件ID是Child,则ID可能会显示为Parent_Child。这将解决ViewState不能正确填充属性或根本不填充问题。