ASP.NET - Preserve child controls state

E

Emil Stoev

Howdy eXperts!

I have this problem w/ my ASP.NET control. The control is a menu with the
following structure:

Menu
Group 1
Item 1
Item 2
Item 3
Group 2
Item 4
Item 5

etc...

What I want is to be able to add controls to any Item. I'm able to do that
but the state is lost and any events fired by those controls could not be
handled correctly.

Here's some of the code (stripped for simplicity):

[assembly:TagPrefix("Menu123.WebControls", "Menu123")]
namespace Menu123.WebControls
{
internal class MyMenuBuilder : ControlBuilder
{
public override bool AllowWhitespaceLiterals()
{
return false;
}
public override Type GetChildControlType(string tagName, IDictionary
attribs)
{
if (tagName.ToLower() == "MyMenugroup" || tagName.ToLower() ==
"Menu123:MyMenugroup")
{
return typeof(MyMenuGroupControl);
}
return null;
}
}

[ToolboxData("<{0}:MyMenu id=MyMenu1 runat=server></{0}:MyMenu>")]
[Designer("Menu123.WebControls.MyMenuDesigner")]
[ControlBuilderAttribute(typeof(MyMenuBuilder))]
[ParseChildren(false)]
public class MyMenu : WebControl, IPostBackEventHandler, INamingContainer
{
private ArrayList _MenuStructure = new ArrayList();
[Browsable(false)]
public ArrayList MenuStructure
{
get
{
return _MenuStructure;
}
set
{
_MenuStructure = value;
}
}

protected override void AddParsedSubObject(object obj)
{
if (obj is MyMenuGroupControl)
{
MenuStructure.Add(obj);
}
}

protected override void Render(HtmlTextWriter output)
{
foreach (MyMenuGroupControl _group in MenuStructure)
{
// Render the group

foreach (MyMenuItemControl _item in _group.GroupStructure)
{
// Render the items

// Render the nested controls here !!! (e.g. add them to table cell,
etc)
}
}
}

protected override object SaveViewState()
{
object baseState = base.SaveViewState();

object[] state = new object[2];
state[0] = (baseState != null) ? baseState : null;
if (MenuStructure != null && MenuStructure.Count > 0)
{
state[1] = new object[MenuStructure.Count];
for (int i = 0; i < MenuStructure.Count; i++)
{
object[] g_state = new object[2];
if (_group.GroupStructure != null && _group.GroupStructure.Count > 0)
{
g_state[0] = new object[_group.GroupStructure.Count];
for (int n = 0; n < _group.GroupStructure.Count; n++)
{
object[] i_state = null;
MyMenuItemControl _item =
(MyMenuItemControl)_group.GroupStructure[n];
if (_item != null)
{
i_state = new object[1];
i_state[0] = _item.Label;
((object[])g_state[0])[n] = i_state;
}
}
}

g_state[1] = _group.Label;
((object[])state[1]) = g_state;
}
}
return state;
}

protected override void LoadViewState(object savedState)
{
if (savedState != null)
{
object[] state = (object[])savedState;

base.LoadViewState(state[0]);
if (state[1] != null)
{
MenuStructure.Clear();
foreach (object[] g_state in (object[])state[1])
{
if (g_state == null) continue;
MyMenuGroupControl _group = new MyMenuGroupControl();
if (g_state[0] != null)
{
foreach (object[] i_state in (object[])g_state[0])
{
if (i_state == null) continue;
MyMenuItemControl _item = new MyMenuItemControl();
_item.Label = (string)i_state[0];
_group.GroupStructure.Add(_item);
}
}
_group.Label = (string)g_state[1];
MenuStructure.Add(_group);
}
}
}
}
}


[System.ComponentModel.ToolboxItem(false)]
internal class MyMenuGroupBuilder : ControlBuilder
{
public override bool AllowWhitespaceLiterals()
{
return false;
}
public override Type GetChildControlType(string tagName, IDictionary
attribs)
{
if (tagName.ToLower() == "MyMenuitem" || tagName.ToLower() ==
"Menu123:MyMenuitem")
{
return typeof(MyMenuItemControl);
}
return null;
}
}

[ControlBuilderAttribute(typeof(MyMenuGroupBuilder))]
[System.ComponentModel.ToolboxItem(false)]
[ParseChildren(false)]
public class MyMenuGroupControl : WebControl
{
public MyMenuGroupControl() {}

protected override void AddParsedSubObject(object obj)
{
if (obj is MyMenuItemControl)
{
GroupStructure.Add(obj);
}
}

private ArrayList _GroupStructure = new ArrayList();
/// <summary>
/// Use this container to programaticaly add Items in the group.
/// </summary>
[Browsable(false)]
public ArrayList GroupStructure
{
get { return _GroupStructure; }
set { _GroupStructure = value; }
}

private string _Label;
/// <summary>
/// Use this property to specify the group label.
/// </summary>
public string Label
{
get { return _Label; }
set { _Label = value; }
}
}

[System.ComponentModel.ToolboxItem(false)]
[ParseChildren(true, "ItemTemplate")]
[PersistChildren(false)]
public class MyMenuItemControl : WebControl, INamingContainer
{
public MyMenuItemControl()
{
_ItemTemplate = new ControlCollection(this);
}
private ControlCollection _ItemTemplate;

[NotifyParentProperty(true)]
[PersistenceMode(PersistenceMode.InnerProperty) ]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ControlCollection ItemTemplate
{
get { return _ItemTemplate; }
}

private string _Label;
/// <summary>
/// Use this property to specify the item label.
/// </summary>
public string Label
{
get { return _Label; }
set { _Label = value; }
}
}
}
 

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

Staff online

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top