Psst! Did you know DevelopmentNow is a mobile web site design agency?

Contact us for help mobilizing your site, or to sign up for our beta Mobile Web SDK!
all groups > asp.net webcontrols > december 2010 >

asp.net webcontrols : Persisting ListItemCollection values across postback, using ViewSt



Christophe Peillet
1/23/2006 8:36:02 AM
I have a series of composite controls to replace most common form controls
(adding Ajax support and a built in validator), and have all of the simple
controls working (textbox, checkbox, button, etc.), but have an issue with
Viewstate and Postback when it comes to ListItem based controls
(CheckboxList, DropDownList and RadioButtonList).

I need to set the Item properties value in Viewstate, but they do not seem
to persist on postback when I do this (all of the other properties do except
this one, so it isn't, I don't think, a problem like unique ID, etc.).

When I set the collection directly to the underlying child control, it works
propertly and persists across viewstates (see first example below), but,
because of other restrictions in my control, I am unable to do this, and NEED
to keep this information in Viewstate, and reassign the appropriate value to
m_chk after a postback.

This is what I have at the moment, which maintains data across postback, but
doesn't work in my case since I need to keep it in Viewstate and manually
reassign it to m_chk.

/// <summary>
/// Gets the CheckBoxList items.
/// </summary>
/// <value>The CheckBoxList items.</value>
[Bindable(true)]
[DefaultValue((string)null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.Design,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
typeof(UITypeEditor))]
[MergableProperty(false)]
[Category("CheckBox")]
public ListItemCollection Items
{
get
{
EnsureChildControls();
return m_chk.Items;
}
}

When I try this, it adds everything to ViewState, but the contents are
always lost on postback.

/// <summary>
/// Gets the CheckBoxList items.
/// </summary>
/// <value>The CheckBoxList items.</value>
[Bindable(true)]
[DefaultValue((string)null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.Design,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
typeof(UITypeEditor))]
[MergableProperty(false)]
[Category("CheckBox")]
public ListItemCollection Items
{
get
{
ListItemCollection l = (ListItemCollection)Viewstate["CheckboxListItems"];
return l;
}
}

How can I persist this information across postbacks, but assigning it to
viewstate.

Thanks for any help on this. (Someone should real write a good book on
custom component development for ASP using real world development examples
(inheritance, etc.) ... there are surprisingly few helpful resources out
stcheng NO[at]SPAM online.microsoft.com
1/24/2006 12:23:26 PM
Hi Christophe,

See you again. How are you doing on your original problems, have you got
them resolved?
As for this problem that use ListItemCollection as custom property and
persist them into ViewState, I think we have to take care of the following
things:

1. ListItemCollection class is not marked as Serializable, so they can not
be directly stored in ViewState collection(can not be persisted in any
other persistent storage suc has file or database.......). The .net 2.0
ListItemCollection class implement the IStateManager interface, we can call
this method to let it help us do generate the data which can be
persisted....

2. For the ListItemCollection, we can just override our custom control's
LoadViewState and SaveViewState methods and manually store their state
value into ViewState collection...... (this is also what asp.net's
buildin ListControl do in their implementation)

In addition, we have to call the TraceViewState method(in IStateManager
interface) when we created the ListItemCollection property's field
instance.... This make sure that our change on the ListItemCollection
instance will be persisted....

here is a test control which demonstrate the above things:

=====================================
namespace WebControlLib
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:LinkListControl
runat=server></{0}:LinkListControl>")]
[Designer(typeof(LinkListControlDesigner),typeof(IDesigner))]
public class LinkListControl : WebControl, INamingContainer
{

private ListItemCollection _items;

[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? String.Empty : s);
}

set
{
ViewState["Text"] = value;
}
}


[Bindable(true)]
[DefaultValue((string)null)]
[PersistenceMode(PersistenceMode.InnerProperty)]

[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.D
esign, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
typeof(UITypeEditor))]
[MergableProperty(false)]
[Category("Data")]
public ListItemCollection Items
{
get
{
if (_items == null)
{
_items = new ListItemCollection();


((IStateManager)_items).TrackViewState();

}

return _items;
}
}


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

LiteralControl lc = new LiteralControl("<table ><tr><td>");
lc.ID = "lc1";
Controls.Add(lc);

if (_items == null || Items.Count == 0)
{
Label lbl = new Label();
lbl.ID = "lblEmpty";
lbl.Text = "No Link in Collection.";

Controls.Add(lbl);
}
else
{
foreach (ListItem item in _items)
{
HyperLink link = new HyperLink();
link.ID = "link" + _items.IndexOf(item);
link.Text = item.Text;
link.NavigateUrl = item.Value;

Controls.Add(link);
Controls.Add(new LiteralControl("<br/>"));
}
}

lc = new LiteralControl("</td></tr></table>");
lc.ID = "lc2";
Controls.Add(lc);

}


protected override void LoadViewState(object savedState)
{
Pair pair = (Pair)savedState;


((IStateManager)_items).LoadViewState(pair.Second);

base.LoadViewState(pair.First);
}

protected override object SaveViewState()
{
Pair pair = new Pair();
pair.First = base.SaveViewState();
pair.Second = ((IStateManager)_items).SaveViewState();


return pair;
}


}

public class LinkListControlDesigner : ControlDesigner
{
public override string GetDesignTimeHtml()
{
StringBuilder sb = new StringBuilder();

LinkListControl llc = Component as LinkListControl;

if (llc.Items == null || llc.Items.Count == 0)
{
sb.Append("<font size='20' color='red'>Empty Link
Collection.</font>");
}
else
{
sb.Append("<font size='20' color='red'>");


foreach (ListItem item in llc.Items)
{
sb.Append("Text: ");
sb.Append(item.Text);
sb.Append(" ");
sb.Append("Value: ");
sb.Append(item.Value);
sb.Append("<br/>");
}

sb.Append("</font>");
}

return sb.ToString();
}
}
}
===================================

Hope helps. Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)






--------------------
| Thread-Topic: Persisting ListItemCollection values across postback, using
ViewSt
| thread-index: AcYgOxl94SUrizHMTcKNRWRECeel7w==
| X-WBNR-Posting-Host: 193.172.19.20
| From: =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=
<ChristophePeillet@nospam.nospam>
| Subject: Persisting ListItemCollection values across postback, using
ViewSt
| Date: Mon, 23 Jan 2006 08:36:02 -0800
| Lines: 72
| Message-ID: <0F8C09F0-A7BB-445E-8BEE-99618F9A2297@microsoft.com>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:32749
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
|
| I have a series of composite controls to replace most common form
controls
| (adding Ajax support and a built in validator), and have all of the
simple
Christophe Peillet
1/26/2006 2:40:04 AM
I have figured out an acceptable solution by using ChildControlCreated =
false in the ViewState properties, and then updating all the mapped
properties in a private method, which is called every time
CreateChildControls is fired.

Thanks for the assistance on this.





[quoted text, click to view]
stcheng NO[at]SPAM online.microsoft.com
1/27/2006 2:29:12 AM
You're welcome Christophe,

Glad that you've got it working.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

--------------------
| Thread-Topic: Persisting ListItemCollection values across postback, using
Vi
| thread-index: AcYiZN5a8L109yEdQx6FVz1pq34rvQ==
| X-WBNR-Posting-Host: 193.172.19.20
| From: =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=
<ChristophePeillet@nospam.nospam>
| References: <0F8C09F0-A7BB-445E-8BEE-99618F9A2297@microsoft.com>
<FcSBEEOIGHA.3696@TK2MSFTNGXA02.phx.gbl>
| Subject: RE: Persisting ListItemCollection values across postback, using
Vi
| Date: Thu, 26 Jan 2006 02:40:04 -0800
| Lines: 313
| Message-ID: <70EC583E-9FE4-4570-9347-C2DFC6238BC8@microsoft.com>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:32823
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
|
| I have figured out an acceptable solution by using ChildControlCreated =
| false in the ViewState properties, and then updating all the mapped
| properties in a private method, which is called every time
| CreateChildControls is fired.
|
| Thanks for the assistance on this.
|
|
|
|
|
[quoted text, click to view]
|
| > Hi Christophe,
| >
| > See you again. How are you doing on your original problems, have you
got
| > them resolved?
| > As for this problem that use ListItemCollection as custom property and
| > persist them into ViewState, I think we have to take care of the
following
| > things:
| >
| > 1. ListItemCollection class is not marked as Serializable, so they can
not
| > be directly stored in ViewState collection(can not be persisted in any
| > other persistent storage suc has file or database.......). The .net
2.0
| > ListItemCollection class implement the IStateManager interface, we can
call
| > this method to let it help us do generate the data which can be
| > persisted....
| >
| > 2. For the ListItemCollection, we can just override our custom
control's
| > LoadViewState and SaveViewState methods and manually store their state
| > value into ViewState collection...... (this is also what asp.net's
| > buildin ListControl do in their implementation)
| >
| > In addition, we have to call the TraceViewState method(in IStateManager
| > interface) when we created the ListItemCollection property's field
| > instance.... This make sure that our change on the ListItemCollection
| > instance will be persisted....
| >
| > here is a test control which demonstrate the above things:
| >
| > =====================================
| > namespace WebControlLib
| > {
| > [DefaultProperty("Text")]
| > [ToolboxData("<{0}:LinkListControl
| > runat=server></{0}:LinkListControl>")]
| > [Designer(typeof(LinkListControlDesigner),typeof(IDesigner))]
| > public class LinkListControl : WebControl, INamingContainer
| > {
| >
| > private ListItemCollection _items;
| >
| > [Bindable(true)]
| > [Category("Appearance")]
| > [DefaultValue("")]
| > [Localizable(true)]
| > public string Text
| > {
| > get
| > {
| > String s = (String)ViewState["Text"];
| > return ((s == null) ? String.Empty : s);
| > }
| >
| > set
| > {
| > ViewState["Text"] = value;
| > }
| > }
| >
| >
| > [Bindable(true)]
| > [DefaultValue((string)null)]
| > [PersistenceMode(PersistenceMode.InnerProperty)]
| >
| >
[Editor("System.Web.UI.Design.WebControls.ListItemsCollectionEditor,System.D
| > esign, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a",
| > typeof(UITypeEditor))]
| > [MergableProperty(false)]
| > [Category("Data")]
| > public ListItemCollection Items
| > {
| > get
| > {
| > if (_items == null)
| > {
| > _items = new ListItemCollection();
| >
| >
| > ((IStateManager)_items).TrackViewState();
| >
| > }
| >
| > return _items;
| > }
| > }
| >
| >
| > protected override void CreateChildControls()
| > {
| > Controls.Clear();
| >
| > LiteralControl lc = new LiteralControl("<table ><tr><td>");
| > lc.ID = "lc1";
| > Controls.Add(lc);
| >
| > if (_items == null || Items.Count == 0)
| > {
| > Label lbl = new Label();
| > lbl.ID = "lblEmpty";
| > lbl.Text = "No Link in Collection.";
| >
| > Controls.Add(lbl);
| > }
| > else
| > {
| > foreach (ListItem item in _items)
| > {
| > HyperLink link = new HyperLink();
| > link.ID = "link" + _items.IndexOf(item);
| > link.Text = item.Text;
| > link.NavigateUrl = item.Value;
| >
| > Controls.Add(link);
| > Controls.Add(new LiteralControl("<br/>"));
| > }
| > }
| >
| > lc = new LiteralControl("</td></tr></table>");
| > lc.ID = "lc2";
| > Controls.Add(lc);
| >
| > }
| >
| >
| > protected override void LoadViewState(object savedState)
| > {
| > Pair pair = (Pair)savedState;
| >
| >
| > ((IStateManager)_items).LoadViewState(pair.Second);
| >
| > base.LoadViewState(pair.First);
| > }
| >
| > protected override object SaveViewState()
| > {
| > Pair pair = new Pair();
| > pair.First = base.SaveViewState();
| > pair.Second = ((IStateManager)_items).SaveViewState();
| >
| >
| > return pair;
| > }
| >
| >
| > }
| >
| > public class LinkListControlDesigner : ControlDesigner
| > {
| > public override string GetDesignTimeHtml()
Greg Kirk
12/1/2010 10:59:01 AM
Exactly what I was looking for, you helped me out a lot. Thanks for the great example! The ViewState can be tricky sometimes.

From http://www.developmentnow.com/g/15_2006_1_0_0_660699/Persisting-ListItemCollection-values-across-postback-using-ViewSt.htm

Posted via DevelopmentNow.com Groups
AddThis Social Bookmark Button