Persisting ListItemCollection values across postback, using ViewSt

C

Christophe Peillet

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
there.)
 
S

Steven Cheng[MSFT]

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?=
<[email protected]>
| Subject: Persisting ListItemCollection values across postback, using
ViewSt
| Date: Mon, 23 Jan 2006 08:36:02 -0800
| Lines: 72
| Message-ID: <[email protected]>
| 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
| 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.D
esign,
| 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.D
esign,
| 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
| there.)
|
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top