This is a vexing question - when you want dynamic controls in ASP.NET web forms you've got to choose the lesser of two evils. Ultimately, it comes down to which compromise you want to make: presenter concerns in the view or view concerns in the presenter.
When I work in web forms I usually prefer the latter - I accept that the presenter is tied to the ASP.NET page lifecycle and create an InitializeView
method to do whatever's necessary to create dynamic controls:
// Presenter
// This could also be parameterless if you prefer that idiom but
// then the view needs a SelectedState property that serves up values
// straight from the Form collection, and it won't be obvious why.
public void InitializeView(string selectedState) {
if (selectedState != null) {
view.Counties = dataLayer.GetCounties(selectedState);
}
}
// View
protected void Page_Init(object sender, EventArgs args) {
presenter.InitializeView(Request.Form["StateList"]);
// ... build counties drop-down ...
}
Of course, this ties the presenter's semantics to the ASP.NET lifecycle and obscures what's going on in that method. You can mitigate that by giving InitializeView
a more descriptive name, like ProcessSelectedState
, but unless the method name references the page lifecycle, it's never going to be obvious why you're not just getting counties with the rest of the model (in presenter.LoadModel
or whatever you might call it).
I can see how the alternative is attractive:
protected void Page_Init(object sender, EventArgs args) {
if (Request.Form["StateList"] != null) {
List<string> counties = presenter.GetCounties(Request.Form["StateList"]);
// ... build counties drop-down ...
}
}
The semantics of the Presenter
are perfectly clear - it's easy to understand what GetCounties
does and it doesn't have anything to do with the page lifecycle. But you have testable stuff in your view, which is a bummer, and that's usually more important to me than keeping my presenters ignorant of their view engine.
Another alternative is to just load your entire model during page initialization. Your server control values won't be available, so you'd have to get any of those from Request.Form
. That's not idiomatic ASP.NET classic though - it might be unduly confusing since most web forms developers are accustomed to getting values directly from web controls instead of directly from the POST data.