Hi, can someone please help me with my custom control viewstate problem....I
haven't slept for hours trying to get this fixed.
I am making two custom controls which will be included on a single page. For
now, I will call them box1 and box2. Each box has a panel and will display a
list of link buttons on the panel.
When the page loads for the first time, box1 will call the database and
create a list of linkbuttons and each link button has a CommandArgument
which represents an ID that will be passed on to box2.
I defined a custom event in box1 which will be fired when a linkbutton is
clicked. In my default.aspx, I capture that event and extract the
commandargument , and then set the ID property of box2 and load another set
of linkbuttons in box2 for that id.
it kinda works for the first half right now, i can load box2's linkbuttons
for the correct id on page postback, however, my problem is that if a
linkbutton in box2 is clicked, when the page reloads, i lose all the
linkbuttons in box2.
I know I need to recreate all the controls in box2 on every postback. But I
just can't get it to work.
My questions are:
First, Is it a good or bad idea to use custom event + property setter to
pass data between controls and trigger the loading of the second box?
I have tried to override the OnInit, CreateChildCont rols(), OnPrerender(),
etc in box2, to check if the ID is in the viewstate from box1, if it is
there, I call the LoadInfoObject( ) method directly. But it didn't work,
viewstate was always null.
so the second question is how and when should I store the ID from box1 in
the viewstate? in which method in box2 can i access that viewstate?
I have attached my code below.
Please enlighten me.
Walter
(BOX1)
InfoChannelsLis tViewer.cs
public event MyEventHandler SelectedInfoCha nnelChanged;
public InfoChannelsLis tViewer() {} //ctor
protected override void CreateChildCont rols()
{
Panel infoChannelsPan el = new Panel();
infoChannelsPan el.EnableViewSt ate = true;
Controls.Add(in foChannelsPanel );
foreach (InfoChannel channel in Db.GetInfoChann els()
{
LinkButton lbtnInfoChannel = new LinkButton();
lbtnInfoChannel .CommandName = "SelectInfoChan nel";
lbtnInfoChannel .CommandArgumen t = channel.ID.ToSt ring();
lbtnInfoChannel .Text = channel.Name;
lbtnInfoChannel .Click += new
EventHandler(lb tnInfoChannel_C lick);
infoChannelsPan el.Controls.Add (lbtnInfoChanne l);
}
}
void lbtnInfoChannel _Click(object sender, EventArgs e)
{
if (sender is LinkButton)
{
LinkButton btn = sender as LinkButton;
if (btn.CommandNam e == "SelectInfoChan nel")
{
//store channel id in viewstate
ViewState["InfoChanne lId"] = btn.CommandArgu ment;
//raise Channel Changed event
MyEventArgs arg = new MyEventArgs
(MyEventType.In foChannelEvent, Convert.ToInt32 (btn.CommandArg ument));
SelectedInfoCha nnelChanged(thi s, arg);
}
}
}
(Box2)
InfoObjectListV iewer.cs
private int _infoChannelId;
public int InfoChannelId
{
get { return _infoChannelId; }
set
{
_infoChannelId = value;
if (_infoChannelId 0)
{
LoadInfoObject( _infoChannelId) ;
}
}
}
private void LoadInfoObject( int infoChannelId)
{
Panel panel2 = new Panel();
this.Controls.A dd(panel2);
foreach (InfoObject obj in Db.GetInfoObjec ts(infoChannelI d)
{
LinkButton infoObjectButto n = new LinkButton();
panel2.Controls .Add(infoObject Button );
infoObjectButto n.CommandName = "SelectInfoObje ct";
infoObjectButto n.CommandArgume nt = obj.ID.ToString ();
infoObjectButto n.Text = obj.Title;
infoObjectButto n.Click += new
EventHandler(in foObjectButtonS endID_Click);
}
}
void infoObjectButto nSendID_Click(o bject sender, EventArgs e)
{
if (sender is LinkButton)
{
LinkButton btn = sender as LinkButton;
if (btn.CommandNam e == "SelectInfoObje ct")
{
this.Page.Sessi on["InfoObject ID"] = btn.CommandArgu ment;
//TODO: further update
}
}
}