Viewstate Dynamically added control (ASP.NET 2.0)

J

jelle.huygen

Hello,

I have a problem in ASP.NET 2.0 with the viewstate of my dynamically
added user control. I have reproduced the problem with a very simple
user control and a very simple page.

On my usercontrol is a button and a label. Everytime the button is
clicked a counter which is stored in the viewstate is increased and
displayed in the label.

The code looks something like this:

Code:
    protected void Page_Load(object sender, EventArgs e)
    {
        btnID.Click += new EventHandler(btnID_Click);
    }

    void btnID_Click(object sender, EventArgs e)
    {
        this.Counter+= 1;
        lblAdd.Text = this.Counter.ToString();
    }

    private int Counter
    {
        get { return this.ViewState["counter"] == null ? 0 :
(int)this.ViewState["counter"]; }
        set { this.ViewState.Add("counter", value); }
    }

On my page is a button. In the event handler of the click event my
user control is loaded and added to a placeholder on my page. When a
postback happens after this, the usercontrol is loaded again in the
Page_Load. This works without any problems: the usercontrol is loaded
and the events of the button on the user control work fine. The code
looks something like this:

Code:
    protected void Page_Load(object sender, EventArgs e)
    {
        btnAddControl.Click += new EventHandler(btnAddControl_Click);

        if (this.Init)
        {
            Test ctrl = this.LoadControl("~/Test.ascx") as Test;
            ctrl.ID = "TEST";
            plcControl.Controls.Add(ctrl);
        }
    }

    void btnAddControl_Click(object sender, EventArgs e)
    {
        Test ctrl = this.LoadControl("~/Test.ascx") as Test;
        ctrl.ID = "TEST";
        plcControl.Controls.Add(ctrl);
        this.Init = true;
    }

    private bool Init
    {
        get { return this.ViewState["init"] == null ? false :
(bool)this.ViewState["init"]; }
        set { this.ViewState.Add("init", value); }
    }

However when I try to initialize my counter with a number after the
load, the value is not saved in the viewstate of the user control. I
added a line to the event handler of the btnAddControl, so it looks
like this:

Code:
    void btnAddControl_Click(object sender, EventArgs e)
    {
        Test ctrl = this.LoadControl("~/Test.ascx") as Test;
        ctrl.ID = "TEST";
        ctrl.Counter = 20;
        plcControl.Controls.Add(ctrl);
        this.Init = true;
    }

When I click the button on the usercontrol the first time the counter
is not in the viewstate and the counter starts from 0. However when I
add the following line to the Page_Load of the usercontrol, the
Counter is initialized correctly to 20:

Code:
    protected void Page_Load(object sender, EventArgs e)
    {
        this.Counter = this.Counter;  //This is the new line!
        btnID.Click += new EventHandler(btnID_Click);
    }

I've read the page lifecycle articles, but I can't see the problem.
The value 20 of the initialization is in the viewstate, but it is not
saved unless I added the last line the the Page_Load event.

Can anyone help me with this problem or explain why the value is not
saved in the viewstate? Any thoughts on adding user controls
dynamically to a page are appreciated as well.

Kind regards,
Jelle
 
K

Kevin Spencer

You're adding "the" Control twice. You're not adding the same instance of a
Control; you're overwriting the first instance the second time you call
"LoadControl." Note that the LoadControl method takes a path to the .ascx
file, but that a Control is an instance of a class. Therefore, when you call
LoadControl, you are creating an instance of the Control's class. Also, here
are the remarks from the documentation regarding the
TemplateControl.LoadControl method:

"When you load a control into a container control, the container raises all
of the added control's events until it has caught up to the current event.
However, the added control does not catch up with postback data processing.
For an added control to participate in postback data processing, including
validation, the control must be added in the Init event rather than in the
Load event."

--
HTH,

Kevin Spencer
Microsoft MVP

Printing Components, Email Components,
FTP Client Classes, Enhanced Data Controls, much more.
DSI PrintManager, Miradyne Component Libraries:
http://www.miradyne.net

Hello,

I have a problem in ASP.NET 2.0 with the viewstate of my dynamically
added user control. I have reproduced the problem with a very simple
user control and a very simple page.

On my usercontrol is a button and a label. Everytime the button is
clicked a counter which is stored in the viewstate is increased and
displayed in the label.

The code looks something like this:

Code:
protected void Page_Load(object sender, EventArgs e)
{
btnID.Click += new EventHandler(btnID_Click);
}

void btnID_Click(object sender, EventArgs e)
{
this.Counter+= 1;
lblAdd.Text = this.Counter.ToString();
}

private int Counter
{
get { return this.ViewState["counter"] == null ? 0 :
(int)this.ViewState["counter"]; }
set { this.ViewState.Add("counter", value); }
}

On my page is a button. In the event handler of the click event my
user control is loaded and added to a placeholder on my page. When a
postback happens after this, the usercontrol is loaded again in the
Page_Load. This works without any problems: the usercontrol is loaded
and the events of the button on the user control work fine. The code
looks something like this:

Code:
protected void Page_Load(object sender, EventArgs e)
{
btnAddControl.Click += new EventHandler(btnAddControl_Click);

if (this.Init)
{
Test ctrl = this.LoadControl("~/Test.ascx") as Test;
ctrl.ID = "TEST";
plcControl.Controls.Add(ctrl);
}
}

void btnAddControl_Click(object sender, EventArgs e)
{
Test ctrl = this.LoadControl("~/Test.ascx") as Test;
ctrl.ID = "TEST";
plcControl.Controls.Add(ctrl);
this.Init = true;
}

private bool Init
{
get { return this.ViewState["init"] == null ? false :
(bool)this.ViewState["init"]; }
set { this.ViewState.Add("init", value); }
}

However when I try to initialize my counter with a number after the
load, the value is not saved in the viewstate of the user control. I
added a line to the event handler of the btnAddControl, so it looks
like this:

Code:
void btnAddControl_Click(object sender, EventArgs e)
{
Test ctrl = this.LoadControl("~/Test.ascx") as Test;
ctrl.ID = "TEST";
ctrl.Counter = 20;
plcControl.Controls.Add(ctrl);
this.Init = true;
}

When I click the button on the usercontrol the first time the counter
is not in the viewstate and the counter starts from 0. However when I
add the following line to the Page_Load of the usercontrol, the
Counter is initialized correctly to 20:

Code:
protected void Page_Load(object sender, EventArgs e)
{
this.Counter = this.Counter;  //This is the new line!
btnID.Click += new EventHandler(btnID_Click);
}

I've read the page lifecycle articles, but I can't see the problem.
The value 20 of the initialization is in the viewstate, but it is not
saved unless I added the last line the the Page_Load event.

Can anyone help me with this problem or explain why the value is not
saved in the viewstate? Any thoughts on adding user controls
dynamically to a page are appreciated as well.

Kind regards,
Jelle
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top