473,385 Members | 1,396 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Controls and ViewState out of sync (?)

Hi,

I'm building a webcontrol that contains a dynamic list of other controls. My
problem is that when I add or remove an item the synchronization between the
ViewState and the Controls collection seems to break -- or at least that's
my theory for now.

Here's what I do; to add an item I do that following on the PostBack of a
button:
1. Create a Button object and set its properties
2. Add the object to the Controls collection
3. Increase a counter (saved in ViewState) that will allow me to rebuild the
Controls collection in CreateChildControls in future PostBacks

When I add a button and set its Text property to "something" that text is
rendered to the browser, but it's not saved in the ViewState; as a
consequence that "something" is lost if I do another PostBack (from a
different control). Removing a control that was added dynamically has
similar issues. If I have, let's say 4 controls, and I try to remove the
second, the second control is removed from the Controls collection, but the
ViewState shifts / gets corrupted(?). For example, let's say the 4 controls
look like this:

[ 1 ] [ 2 ] [ 3 ] [ 4 ]

We want to delete the second control; after removing the second control the
output is:

[ 1 ] [ 3 ] [ 4 ]

which is what we want. Unfortunately, on a subsequent PostBack, the list
becomes:

[ 1] [ ] [ 3 ]

which basically tells me that the ViewState got out of sync with the number
of control in the Controls collection.

Is my theory correct, is there a way to fix this problem? I've attached a
simple test project to exemplify my problem.
Any help / suggestion is welcome, thanks!
Peter.
----- WebForms1.aspx ---- (the relevant part)

<form id="Form1" method="post" runat="server">
<asp:Panel Runat=server ID="pnlTest"></asp:Panel>
<br>
<asp:Button Runat=server id="btPostBackTest" Text="Test"></asp:Button>
</form>

----- WebForms1.aspx.cs ---- (the relavant pieces)

private void WebForm1_Init(object sender, System.EventArgs e)
{
ControlList cl = new ControlList();
pnlTest.Controls.Add(cl);
}

private void btPostBackTest_Click(object sender, System.EventArgs e)
{
// do nothing... just a postback test
}

----- ControlList.cs ----- (the file that holds the ControlList class)

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

[ ... ]

public class ControlList : WebControl, INamingContainer
{
public ControlList()
{
//
// TODO: Add constructor logic here
//
}

private Button _btAdd;
private Button _btDelete;

public int ItemCount
{
get
{
object count = ViewState["count"];
return ((count == null) ? 0 : Convert.ToInt32(count));
}
set
{
ViewState["count"] = value;
}
}

private TextBox NewButton(int index)
{
TextBox t = new TextBox();
Controls.Add(t);
t.ID = "tb" + index.ToString();
return t;
}

protected void OnAddClick(object sender, System.EventArgs e)
{
ItemCount++;
TextBox t = NewButton(ItemCount);
// at this stage t is already in the Controls collection, but
// the modified text value below doesn't save to the ViewState (why?)
t.Text = "something #" + ItemCount.ToString();
}

protected void OnDeleteClick(object sender, System.EventArgs e)
{
// to make it simple we always try to delete the second textbox
(id=tb1)
Control c = FindControl("tb1");
if (c != null)
{
ItemCount--;
// this seems to messup the sync btw Controls and ViewState
Controls.Remove(c);
}
}

public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}

protected override void CreateChildControls()
{
Controls.Clear();

_btAdd = new Button();
Controls.Add(_btAdd);
_btAdd.ID = "btAdd";
_btAdd.Text = "Add";
_btAdd.Click += new EventHandler(OnAddClick);

_btDelete = new Button();
Controls.Add(_btDelete);
_btDelete.ID = "btDel";
_btDelete.Text = "Delete";
_btDelete.Click += new EventHandler(OnDeleteClick);

for (int i = 0; i < ItemCount; i++)
{
NewButton(i);
}
}
}

Jan 19 '06 #1
6 4393
sam
Yeah.

Viewstate is saved by control index *only* (ie. 1, 2, 3), not ID.
Microsoft did this to save space in the viewstate string. Please
google viewstate for more information.

What most ppl do is always build 4 controls and then on PreRender() set
the visibility of the ones they don't want to false. That way the
viewstate is always restored correctly.

If you want to talk more about this i'll answer.

-Sam

Jan 19 '06 #2
> Viewstate is saved by control index *only* (ie. 1, 2, 3), not ID.
Microsoft did this to save space in the viewstate string. Please
google viewstate for more information.
I've read about how the ViewState and the Controls collection sync that's
what made me think that they were getting out of synch somehow. Just to be
sure: are you saying that it can't be done? (creating a dynamic number of
controls in a postback event i.e.). I guess I am hoping that there may be a
trick to do this; I mean, the PostBack occurs before the ViewState is saved,
so why not be able to alter the ViewState to be in sync with the Controls
collection, or am I missing something?
What most ppl do is always build 4 controls and then on PreRender() set
the visibility of the ones they don't want to false. That way the
viewstate is always restored correctly.
That will work for some cases, but not for everything -- cool trick
though...
Any idea if the 2.0 framework has the same issue?
If you want to talk more about this i'll answer.


Thanks for your time!
Jan 19 '06 #3
sam
You could get the viewstate of the child controls (by getting ViewState
property - it's type StateBag) and save *that* in the viewstate of the
ControlList under some unique key (child control index?). The
ControlList viewstate shouldn't get messed up becuase you are always
adding it to the page in the same place on postbacks (hopefully).

I don't think ASP.NET 2.0 solves your problem. The viewstate is twice
as small and they have a new ControlState(?) which works even if
ViewState of parent is turned off. Maybe ControlState works without
indexing the control tree. Can you find out and tell me? LOL.

-Sam

Jan 19 '06 #4
Thanks.
Jan 20 '06 #5

Peter Zolja wrote:
Thanks.


The way we handled it was:

1. Always re-load the controls on postback, so viewstate doesn't break
(load in order according to step 4).

2. Conditionally handle any events that get fired once the controls
are re-loaded

3. With some logic, conditionally remove the controlls we didn't want.

4. Load in the controls as required

5. Remember (usually with viewstate), the order and type of controls.
1. we use a hashtable with Key = position and string = control
type

Does this make sense?

thanks,

bill

Jan 28 '06 #6
sam
It makes sense, if you don't want to do the visibility trick.

Sorry, but I forgot to mention. Maybe you already know this. If you
set viewstate to false in the parent control it will be turned off in
all child controls so you won't get that error message again, no matter
what you do with the child controls. I thought this was what you were
going to do.

Of course, you do have to load all the controls if you want to catch
their events. Then you either remove them or set visibility to false.

Feb 4 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Steve Drake | last post by:
All, I have a CONTROL that contains 1 control (Control ONE), the 1 control that it can contain 1 or 2 control (Control A and B). Control A, raises and event and Control ONE receives this event...
8
by: Invalidlastname | last post by:
Hi, We are developing an asp.net application, and we dynamically created certain literal controls to represent some read-only text for certain editable controls. However, recently we found an issue...
4
by: Chuck Ritzke | last post by:
Hi, I've searched the newsgroup and other sources to understand how to handle runtime controls and see I'm not the only one who's confused, but I'm still not quite sure of the best way to handle...
2
by: Chad | last post by:
I have a problem that I am desperate to understand. It involves dynamically adding controls to a Table control that is built as a result of performing a database query. I am not looking to...
0
by: Don | last post by:
I need some suggests on how to manage the viewState on my page. I have multiple checkBoxLists that are dynamically created and need then synced up with the viewstate. My problem is that on each...
3
by: Ankit Aneja | last post by:
I have a strange situation and I have no idea how to solve this. Its a Recruitment Search Page,in the Admin Page, for every button click event the Admin Person has to create a checkbox on the users...
0
by: Scott Roberts | last post by:
I always thought that the viewstate "keys" included the control ID. As long as the control IDs were unique, there shouldn't be any conflicts. Well, it appears that that may not be the case with...
1
by: MaryamSh | last post by:
Hi, I am creating a Dynamic Search in my application. I create a user control and in Page_load event I create a dynamic dropdownlist and 2 dynamic button (Add,Remove) By pressing Add button...
0
by: MaryamSh | last post by:
Create Dynamic Dropdownlist Controls and related event -------------------------------------------------------------------------------- Hi, I am creating a Dynamic Search in my application. I...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.