C#: Callback & ViewState
Posted: Sun Mar 01, 2009 1:51 am
I need a solution that allows me to store a user control property in the viewstate after a callback. I tried hacking it like this:
Persister.cs
Searchbox_Combobox_Base.cs:
AS_SearchDialog.cs:
Alright. So I have a pop-up that has two listboxes, and items are moved between the two listboxes. The 2nd listbox becomes the multiple selection items -- so the user control that contains the combo box also contains a ComboBoxItemCollection named 'selections', you see. And if there has been a multiple selection, then I need to draw the items from this member. The thing is, this isn't automatically saved (perhaps because it's not serializable), so I go to lengths to convert it to an array and save it to the viewstate, and then convert from an array in the viewstate and repopulate the selections member for LoadViewState.
The problem is, that the view state is saved correctly. Then when it goes to be loaded, the view state is no longer populated. So it gets out of sync somehow. IOW if I step through it then when the SaveViewState is triggered, the ViewState takes the information okay. Then when the page is reloaded from the Callback, when it comes to be time to load the ViewState information, the information isn't there any more.
Basic research I've found is http://aspadvice.com/blogs/joteke/archi ... backs.aspx and http://forums.asp.net/p/895595/967316.aspx#967316 neither of which are much help at ~3am.
Also this uses the ComponentArt CallBack control but it shouldn't make any real difference no matter how a Callback is handled.
Anyone know C#/ASP.NET that can help me with this?
Edit: Oh yeah, doing this because otherwise when I hit the execute search button, I lose the information before I can run the search.
Persister.cs
Code: Select all
[AttributeUsage(AttributeTargets.Property)]
public class PersistToViewState : Attribute { }
public class Persister : UserControl
{
protected override void LoadViewState(object savedState)
{
if (savedState == null)
return;
base.LoadViewState(savedState);
PropertyInfo[] properties = GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
object[] attributes = property.GetCustomAttributes(typeof(PersistToViewState), true);
if (attributes.Length > 0)
{
if (ViewState[property.Name] != null)
property.SetValue(this, ViewState[property.Name], null);
}
}
}
//Need to be able to trigger SaveViewState after a callback
public object SaveViewStatePub() {
return SaveViewState();
}
protected override object SaveViewState()
{
PropertyInfo[] properties = GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
object[] attributes = property.GetCustomAttributes(typeof(PersistToViewState), true);
if (attributes.Length > 0)
ViewState[property.Name] = property.GetValue(this, null);
}
return base.SaveViewState();
}
}
Code: Select all
public abstract class Searchbox_Combobox_Base : Persister { //please pardon the confusing class name.
public ComboBoxItemCollection selections = new ComboBoxItemCollection();
[PersistToViewState]
public ComboBoxItem[] Selections
{
get
{
ComboBoxItem[] retval = new ComboBoxItem[selections.Count];
int i = 0;
foreach (ComboBoxItem item in selections)
{
retval[i] = selections[i];
i++;
}
return retval;
}
set
{
foreach (ComboBoxItem item in (ComboBoxItem[])value)
{
selections.Add(item);
}
}
}
Code: Select all
/// <summary>
/// Grabs the ListItemCollection generated by Search_Multiselect.aspx from Session[id]
/// and copies it to the selections property of the combobox with the ID of 'id'.
/// </summary>
/// <param name="id">ID of the control to search the page for and populate</param>
private void MakeComboboxMultiselect(string id)
{
ListItemCollection items = (ListItemCollection)Session[id];
if (items == null || items.Count == 0)
return;
Control control = Page.FindControl(id);
if (control is Searchbox_Combobox_Code)
{
Searchbox_Combobox_Code box = (Searchbox_Combobox_Code)control;
box.Text = "Multiselect";
foreach (ListItem listItem in items)
{
ComboBoxItem comboItem = new ComboBoxItem();
comboItem.Text = listItem.Text;
comboItem.Value = listItem.Value;
box.selections.Add(comboItem);
}
box.SaveViewStatePub();
}
Session[id] = null;
}
//Updates the combo boxes
protected void clbUpdatePage_Callback(object sender, CallBackEventArgs e)
{
MakeComboboxMultiselect(e.Parameters[0]);
clbUpdatePage.Content.RenderControl(e.Output);
}
The problem is, that the view state is saved correctly. Then when it goes to be loaded, the view state is no longer populated. So it gets out of sync somehow. IOW if I step through it then when the SaveViewState is triggered, the ViewState takes the information okay. Then when the page is reloaded from the Callback, when it comes to be time to load the ViewState information, the information isn't there any more.
Basic research I've found is http://aspadvice.com/blogs/joteke/archi ... backs.aspx and http://forums.asp.net/p/895595/967316.aspx#967316 neither of which are much help at ~3am.
Also this uses the ComponentArt CallBack control but it shouldn't make any real difference no matter how a Callback is handled.
Anyone know C#/ASP.NET that can help me with this?
Edit: Oh yeah, doing this because otherwise when I hit the execute search button, I lose the information before I can run the search.