Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Dynamic controls ,Page Life Cycle, MultiView and Wizard

0.00/5 (No votes)
20 Feb 2007 1  
Best Practices in ASP.NET for writing User Control In MultiView And Wizard using Dynamic controls

Introduction

It seems to me that the page life cycle is not understood properly and with proper coding,
we can get rid of most of the problems.

IN this Article I have covered three topics

  • Where to create Dynamic Control when Dynamic control is created in DataBound
    Controls
  • How to Deal With Issue that Page_Load of all controls inside MultiView is called
    irrespective of whether view is active or not.
  • What is the Best practice of writing UserControl that can reside in MultiView
  • I Have touched upon Page Life cycle in regard to Dynamic control creation

Generally, we have been adding code in Page_Load of controls. We can do that as long
as we know this control is always going to be a direct child of the page, which may not
always be the case(For Example you have a User Control in MultiView or Wizard).Calling
Initialization logic in Page_load will be a performace hit because Page_load of all Views in
MutiView will be called anyway even if view is not going to be Visible.There is no point in
Doing dataBinding in Page_load. Page.ISPostBack is always true in MultiView And Wizard
even if this
is the first time View is going to be Visible So You need custom logic to determine if it is
postback.PLease read Item (4) to find out how you can deternine real postback has
happened while view is visible.

Note: These recommendations should be valid for both MultiView and Wizard.

I have written these FAQ to cover all the Major bulleted points i have described in article

  1. What is the best way to initialize a control which is inside a MultiView?

Call Initialize method of control inside a MultiView, when needed, on appropriate events
such as ActiveViewIndexChanged or Page_Load.Initialize Method can take correct
parameters for either post back, or data binding.Initialize method can call DataBinding of
control (Explicit DataBinding)when control is not implicitly data bound using
ObjectDataSource. If you don't know What ObjectDataSource is or What is Implicit
DataBinding then PLease read some good book on ObjectDataSource. I will try to cover it
here in Few Lines. In Your UserCOntrol Supppose you have a FormView. FormView has
Property called DataSourceID.This Property is used to Bind the control with
SQLDataSource or ObjectDataSource. using SQLDataSource is not a good design because that way you are binding UI with DataAccessLayer. using ObjectDataSource you can Tie
UI elements line FormView to Business Entities. BusinessEntities Properties can be Bound
to UI elements.

If you type following code in ASCX file

asp:ObjectDataSource id=ObjectDataSource1 CacheExpirationPolicy="Sliding" 

CacheDuration="300" TypeName="DataAccess" 

SelectMethod="GetData" runat="server">

<SELECTPARAMETERS>

<asp:Parameter Direction="input" Type="string" Name="p_sortExpression">

</asp:Parameter>

<asp:Parameter Direction="input" Type="string" Name="p_sortDirection">

</asp:Parameter>

</SELECTPARAMETERS>

</asp:ObjectDataSource>

Now in your FormsView DataSourceID=ObjectDataSource1 then DataAccess Object(see
TypeName property above) is used for binding the FOrmView Implicitly.
WhenEver this user control is shown on the Page DataBinding automatically gets called for
this control. This is called Implicit DataBinding. You Can Do Explicit DataBinding by calling
FormView.DataBind() also when needed but it is not required.

PLease see an Example of Explicit DataBinding in Item Number 7)

2) Where to create dynamic control - in Page_Init, Page_Load, LoadViewState or
PreRender?

The best place is Page_Init and LoadViewState. LoadViewState is called only on post
back. If done here, then In Page_Load you have access to all the control's Postback
data.

Please read this article to understand the page life cycle:

Please also Look into this eye opening article about dynamic controls:

I have tried to Cover everything what should be known by creating Few FAQ's

is a method which should be implemented by each control. Its responsibilities could
include:http://aspalliance.com/articleViewer.aspx?
aId=134&pId
.http://weblogs.asp.net/infinitiesloop/archive/2006/08/25/TRULY-
Understanding-Dynamic-Controls-_2800_Part-1_2900_.aspx
.

3) Where to do data binding in control?

There are two solutions:

  • Use ObjectDataSource in ASCX file as Explained in Item Number 1). ASP.NET
    takes care of calling data binding when view is going to be active. All you have to
    do is pass some information into the control to the Initialize method from the
    parent ActiveIndexChanged event handler and implicit data binding automatically
    happens after that at the proper stage in the page life cycle.
  • Call Initialize from ActiveIndexChanged event handler when inside parent
    MultiView,
    which in turn does explicit data binding. Since ActiveIndexChanged
    event is called after ProcessPostBackData2 (See Page Life Cycle), this means
    that if data binding happens at this time and dynamic controls are created as a
    result of that, then you have to be careful about recreating those control in post
    back of the view. I will Explain this further below.

4) If I have a Repeater or FormView which creates dynamic controls, what is the
best event for handling the creation process - ItemDataBound or ItemCreated?
If
created in any of these events then when to create dynamic control in
PostBack?

ItemCreated Event

To make this model work, declare OnItemCreated event in ASCX file not by attaching
events in Page_Load because Page_Load happens too late in the life cycle. I will explain
the reason for that later in this section.

ItemDataBound event is called only when when DataBinding happens. ItemCreated
event is called both when DataBinding happens and when PostBack happens with no
DataBinding
.

So, the best place for creating dynamic control is ItemCreated event. When it is a
PostBack, ItemCreated event is called before Page_Load with DataItem=NULL. When
ItemCreated is called as a result of DataBinding then DataItem != null.

What is happening behind the scenes for the PostBack scenario is: ASP.NETrecreates
each item in the Repeater control during the Repeater's LoadViewState method,
which in turn raises ItemCreated event with DataItem=NULL because Data Binding is not
happening, only controls are being recreated.

So, if DataItem==NULL and Visible property is true in ItemCreated event this means that

it is a PostBack on the same control back again while it is visible. Here you can recreate
the dynamic control to make sure that by the time the Page_Load is called you have the
Postback data for these controls.Add further discussion of dynamically created invisible
controls here.

So in no case can I think of where you need to call Rebind from within Page_Load. If you
still have to do that, then since ItemCreated event happens before Page_Load you can
use that to flag the PostBack and implement your own custom logic. Don't try to Rebind in
Post Back from within the control Page_Load � unless there is a compelling reason to do
that. In most cases, let the parent container handle it.

For example, if you have a Repeater, which adds items (children) in the PostBack and
then want to rebind, one way is to raise an event in the parent to rebind itself. Another
way is to let the page handle itself as discussed above.

5) Can I do DataBinding in Prerender? If yes, can I create dynamic control there?

Yes, you can, but remember that any dynamic control created there will not have its
PostBackData available in PostBack. So, be careful while doing it. Also, any event
handlers attached to the dynamic control at this time will not be executed at all.

6) If I am creating a control by myself and not using DataBound controls, how can
I Initialize that control in PostBack when inside Multiview ?

The parent Page_Load method should take care of calling Initialize on the created
control which in turn calls for creating a dynamic child control. At this time, the
Page_Load
of the child is not called, so you can create these dynamic controls right
there within Initialize. If you want you can call DataBind, too

In web page Page_Load handler:

protected void Page_Load(object sender, EventArgs e)
{
MultiView1.ActiveViewChanged += 
new EventHandler(MultiView1_ActiveViewChanged);

reviewDepControl.EditDependentClick +=
 new OnEditDependentEventHandler(OnEditDependentClick);

editDependentControl.DoneEditingDependent +=
 new OnDoneEditingDependentEventHandler(OnDoneEditingDependent);

//if not a postback, call init on the correct control

if (!IsPostBack)
{
if (MultiView1.ActiveViewIndex == 0)
{
reviewDepControl.Initialize(2, false);
}
else if (MultiView1.ActiveViewIndex == 1)
{
editDependentControl.Initialize(false);
}
}
else
{
if (MultiView1.ActiveViewIndex == 0)
{
reviewDepControl.Initialize(2, true);
}
else if (MultiView1.ActiveViewIndex == 1)
{
editDependentControl.Initialize(true);
}
}
}

Here, the second property tells if it is a Initialize with a Rebind required or not.

There is also an ActiveIndexChanged event in a MultiView which we can be used to rebind
the control as I explained in earlier section for first time Initialization.

void MultiView1_ActiveViewChanged(object sender, EventArgs e)
{
if (MultiView1.ActiveViewIndex == 0)
{
reviewDepControl.Initialize(2, false);
}
else if (MultiView1.ActiveViewIndex == 1)
{
editDependentControl.Initialize(false);
}
}

There is another solution to this also. Use the LoadViewState method of your control in
PostBack to create a dynamic control but parent can call Initialize method to make some
decision if required. Most of the time it is not the case. This Initialize should be called
from Page_Load only.

7) Try to use the controls available in the Framework and ObjectDataSource. This
will take care of firing events at right time instead of putting your own custom logic
to mimic that same functionality � unless there is a compelling (and valid) reason
to do so.

8) When I have DataBound control in one of the Views in a MultiView, how can I call
Initialize method on the control in PostBack just to make sure that the dymanic

controls are created properly?

You cannot use the method described in 6) for DataBound control just for creating
dynamic controls in PostBack . You need to rely on the techniques I have discussed in
Item 4). Use the ItemCreated event.If you need an Example PLease send me an Email

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here