Loading one user control after another has loaded - ASP.NET WebForms
I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I pr开发者_如何学运维efer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible).
- If I add user controls on the page at compile time and set visible to false for User Control B, does it still execute the B's code behind? I can then set the visibility to true after loading User Control A
- Should I be using events/delegates for notifying the completion of loading User Control A?
Don't load everything in the page event in control b, just put a method on control b to be called. Then add an event to control a which the page consumes, when the event is raised, call the load method on control b.
Edit: SampleCode
Ok so for example, create
- a ASPX page
- 2x user controls
Put both user controls into the aspx page.
<cc:control1 runat="server" id="control_one" />
<cc:control2 runat="server" id="control_two" />
Then in control 1, create a delegate and event.
public delegate void MyCustomEvent (EventArgs args);
public event MyCustomEvent MyEvent;
protected void Page_Load(object sender, EventArgs e)
{
MyEvent(e);
}
So I have the event raised on page load. So you would have your logic in there thats required, when your done, calls MyEvent event.
In the page you want to add a handler for that event so when it's called you can do something with it.
protected override void OnInit(EventArgs e)
{
control_one.MyEvent += new WebUserControl1.MyCustomEvent(control_one_MyEvent);
base.OnInit(e);
}
void control_one_MyEvent(EventArgs args)
{
control_two.MyCustomLoad();
}
So when the page is initialized I add the event handler. In the event handler I call a custom method on the second control to load stuff.
Then in the second control I have:
public void MyCustomLoad()
{
//Stuff only loaded when event is raised and calls this method.
}
So this allows control 1 to load something, say it's done, when the page knows it's done, it can tell control 2 to do something.
Edit: After discussing this with a friend I'll explain what I mean by controlling the order.
You cannot control the order of page-life-cycle events. i.e: You can't have Control A, run through all it's page-life-cycle events, then once it's done, have Control B run through all it's page-life-cycle events.
If you do-away with the page life cycle, you can do a degree, as my example above shows, create a way of controlling the order in which the controls are rendered. By raising an event(s) at certain points when Control A is finished, you can tell Control B to do something.
The intermediate between the two controls is the page which handles the events raised by Control A which calls a method on Control B. You (well you can hack around to do it) can't specifically make Control A tell Control B to do something because that creates a direct dependency between the two controls which is bad.
- Yes, the code behind will still run
- Events could be useful
But if your controls have a specific dependency on each other, maybe they should just be a single control?
This is a fatally-flawed design. You should design your UI so that it doesn't matter in what order the controls load. The order in which controls load is outside of your control.
To address "Phill's" issue with an Order/Orderlines control pair:
I assume that the Order control was developed because it's useful by itself. I assume that OrderLines was developed to be able to show the line items for a given order displayed by the Order control.
I contend that there should be a single, composite control which combines Order and OrderLines. this control will pass to the OrderLines control, a DataSource consisting of the line items it is to display. This makes OrderLines independent of any other control - it simply displays the data it is told to display. It has no idea where that data came from.
Note that this can extend to a typical grid / detail / detail lines scenario, where you pass the grid a set of orders; when selected, a particular grid row will pass the Order control the selected order; when its' time to display the line items, pass the line items collection of the current order to the OrderLines control, etc.
This leaves each control with nothing to do but the Single job it is Responsible for.
"I have a UserControl A that has to be loaded first and after that completes loading, I need to load a UserControl B.
I prefer to add both these user controls on the page at compile time (would like to avoid dynamic loading if possible). "
I would suggest using WebFormsMVP: -
http://webformsmvp.com/ http://wiki.webformsmvp.com/index.php?title=Main_Page
As well as being a good implementation of Model-View-Presenter, one of the most useful features of this framework is its support for Messaging.
In a nutshell, you create Message Types, and your usercontrols (views) can post messages of whichever type you need to a message bus. Other controls can subscribe to messages of a particular type and the WebFormsMVP framework will ensure they are delivered.
This allows you to handle interaction between usercontrols by messaging publish & subscribe, without worrying about which order they load in.
Your only other option is to use dynamic control loading because, as others have pointed out, you can't rely on the order in which ASP.NET loads controls into a container.
精彩评论