Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with dynamic controls

Status
Not open for further replies.

afroblanca

Programmer
Jul 15, 2005
67
US
Hello all,

I'm wanting to create some dynamic controls, and have them persist their viewstate across page loads. Easy enough, right? All I have to do is re-create the controls upon each page load, using the same IDs. HOWEVER, here's the catch - in my PreRender event, I'm wanting to clear the controls collection, and then recreate the dynamic controls with new values. The reasons for this are complicated, and it would probably take me about a page or so to explain why I want to do it. So, in the interests of brevity, let's just assume that I absolutely must do this, and that there's no other way.

The problem comes in after I re-create the controls in my PreRender event. The re-created controls never bind to the viewstate, and their values do not persist across page loads. I don't understand why this happens. I'm already re-creating the controls in my OnLoad event. When I do this, the newly created controls bind to the ViewState just fine, provided that I use the same IDs every time. However, when I try to do the same thing in the PreRender event, it fails.

In any case, here is my example code :

namespace TestFramework.WebControls
{
public class ValueLinkButton : LinkButton
{
public string Value
{
get
{
return (string)ViewState[ID + "vlbValue"];
}

set
{
ViewState[ID + "vlbValue"] = value;
}
}
}

public class TestControl : WebControl
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);

Controls.Clear();

ValueLinkButton tempLink = null;

tempLink = new ValueLinkButton();
tempLink.ID = "valueLinkButton";
tempLink.Click += new EventHandler(Value_Click);

if (!Page.IsPostBack)
{
tempLink.Value = "old value";
}

Controls.Add(tempLink);
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

ValueLinkButton tempLink = ((ValueLinkButton)FindControl("valueLinkButton")); //[CASE 1]

//ValueLinkButton tempLink = new ValueLinkButton(); [CASE 2]

tempLink.ID = "valueLinkButton";
tempLink.Value = "new value";
tempLink.Text = "Click";

Controls.Clear();
Controls.Add(tempLink);
}

void Value_Click(object sender, EventArgs e)
{
Page.Response.Write("[" + ((ValueLinkButton)sender).Value + "]");
}
}
}

So, let's examine case 1, where the line next to [CASE 1] is not commented out, but the line next to [CASE 2] is commented out. Here, everything works just fine. When I put this control on a page and load the page, I see a link that says "Click". When I click the link, the page outputs the text "[new value]", and on the next line, we see the familiar "Click" link. Every subesquent time I click on the "Click" link, we see the same thing. So far, so good.

But now let's examine case 2, where the line next to [CASE 1] is commented out, but the line next to [CASE 2] is not commented out. Here we run into problems. When we load the page, we see the "Click" link. However, when I click on the link, the page outputs the text "[]" instead of "[new value]". The click event is firing normally. However, the "new value" text that I assigned to the Value attribute of the control does not get persisted. Once again, this is a bit of a mystery to me. How come, when I recreate the control in OnLoad, everything's fine and dandy, but when I recreate the control in PreRender, the value doesn't get persisted?

I feel like there simply has to be a way to do this. When I re-create the control in PreRender, is there some way to bind the newly created control to the ViewState?

I've struggled with this for days. Any help that you can give me will be appreciated.

Thanks.
 
The reasons for this are complicated, and it would probably take me about a page or so to explain why I want to do it. So, in the interests of brevity, let's just assume that I absolutely must do this, and that there's no other way.
i would recommend discussing this portion of your topic in forum678. My thoughts about this comment are:
1. break the complexity into smaller simple chunks
2. the fact that this is so complex could be a code smell. This can't be determined without more information though.

As for viewstate, I believe controls must be added during the Init event of the page life cycle. properties and values can be added during PageLoad.
Code:
private LinkButton link;

protected override void OnInit(EventArgs e)
{
   base.OnInit(e);
   link = new LinkButton();
   link.ID = "foo";
   Controls.Add(link);
}

protected override void OnLoad(EventArgs e)
{
   base.OnLoad(e);
   link.Click += DoSomething;

   if(!IsPostBack)
   {
      //initial logic
   }
   else
   {
     //returning to page
   }
}

private void DoSomething(object sender, EventArgs e)
{
   Debug.WriteLine("{0} exists: {1} ", link.ID, FindControl("link.ID") != null);
}

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top