Server control and view state

It's time to show the complete lack of knowledge for all web forms, but here. I am extending the Control Panel and OnPreRender by inserting some additional controls inside it (just say 1 textbox for simplicity). From here, I just let the Panels Render method do its thing.

The problem I am running into is that obviously every time this control reloads it just adds the same TextBox to the panel again with the value that I code in the OnPreRender method. Now I don't want to re-fill the panel every time,

I want to bind the contorl textbox there to the first load and reload them from the control / viewstate cache. In this case, with my example, just stick with one textbox in the panel, if the value of the textbox changes and postback occurs, I want that value to remain the changed value.

In fact, basic web forms stuff that I know, but I've never had to create custom controls in my time. Any help was appreciated.

Chris.

+1


source to share


4 answers


You need to (re) create the child control (textbox) in OnInit - so that it appears where LoadViewState and ProcessPostBackData are called.



See the Server Management Lifecycle for more information .

+3


source


Dynamic controls in ASP.NET are tricky, especially if you're new to Web Forms and the page lifecycle. If you can avoid dynamic control, do so. Use controlName.Visible = false and other tricks.



If you must read this article . Rule of thumb, add controls early in the page lifecycle, describe them later in the page lifecycle. PreRender is almost the very end, an unusual place to add and use controls.

+1


source


Not sure if this applies to all .Net versions (2.0 or newer I think), but there is a method called CreateChildControls that is not actually part of the lifecycle, it is basically called anytime the EnsureChildControls method is called. By default it is called before the PreRender if it is not a postback. So basically your code will look like this:

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

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

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

    Controls.Add(textboxToCheck);
  }
}

      

Now, lest the part be, unless you call EnsureChildControls, you cannot be 100% sure that the controls exist before the shared properties of your control are populated by loading the ViewState. What does it mean? Well take the code from earlier and add a property for the 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; }
}

      

In CreateChildControls, you don't want this:

someTextBox.CssClass = CssClass;

      

Since there is no way to make sure the control exists. There are several ways you can handle this:

public String CssClass {get {EnsureChildControls (); return someTextbox.CssClass; }

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

      

In this example, I am calling EnsureChildControls (Assuming you are setting the CssValue on the text box in the CreateChildControls method) and setting or getting from the text box.

Another way is that everything depends on the public properties of the control in the OnPreRender method:

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

      

This way, avoid the clutter of worrying about the property being populated already at the time the ViewState is loaded.

One note:

Using INamingContainer can be important. Basically what it all does is that the controls of the parent control have a unique ID on the page by applying the parent name (and maybe more) to the ID. Basically, if the parent ID is the parent and the child ID is the child, the ID can appear as Parent_Child. This will fix issues with ViewState not populating properties correctly or not at all.

+1


source


Within your code, you will need to manage the recovery of the view information if you need viewstate services.

A good example here is Microsoft's State View Sample . There are several other elements in the sample code, but that should get you on the right track.

0


source







All Articles