1

好吧,是时候展示我对所有 Web 表单的知识完全缺乏了,但是就到这里吧。我正在扩展 Panel 控件和 OnPreRender 在其中粘贴一些其他控件(为简单起见,我们只说 1 个文本框)。从这里我只是让 Panels Render 方法做它的事情。

我遇到的问题是,显然每次重新呈现此控件时,它只是将相同的 TextBox 再次粘贴在面板中,并使用我在 OnPreRender 方法中编码的值。现在我实际上不想每次都重新填充面板,

我想在第一次加载时将文本框控件粘贴在那里,并让它们从控件/视图状态缓存中重新加载。在这种情况下,以我在面板中仅粘贴单个文本框的示例为例,如果文本框的值发生更改并且发生回发,我希望该值保持更改后的值。

我知道的非常基本的网络表单东西,但我从来没有在我的时间里创建自定义控件。任何帮助表示赞赏。

克里斯。

4

4 回答 4

3

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

有关详细信息,请参阅服务器控制生命周期

于 2008-12-08T16:51:44.997 回答
1

ASP.NET 中的动态控件很棘手,尤其是当您不熟悉 Web 表单和页面生命周期时。如果您可以避免动态控制,请这样做。改用 controlName.Visible=false 和其他技巧。

如果你一定要读这篇文章。经验法则,在页面生命周期的早期添加控件,在页面生命周期的后期引用它们。PreRender 几乎是最后,一个不常见的添加和使用控件的地方。

于 2008-12-08T16:49:28.527 回答
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,否则在 ViewState 负载填充控件上的公共属性之前,您不能 100% 确定控件存在。这是什么意思?好吧,取之前的代码并为 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(); 返回一些Textbox.CssClass;}

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

在此示例中,我正在调用 EnsureChildControls(假设您在 CreateChildControls 方法中的文本框上设置 CssValue)并从文本框中设置或获取。

另一种方法是将依赖于控件公共属性的任何内容放在 OnPreRender 方法中:

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

从而避免了在 ViewState 加载期间担心属性已经被填充的混乱。

一注:

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

于 2008-12-08T17:11:46.097 回答
0

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

这里的一个很好的例子是Microsoft 的View State 示例。代码示例中还引用了其他一些项目,但它应该能让您走上正确的道路。

于 2008-12-08T16:48:43.740 回答