A framework issue rather than a pure C# issue, so a little off topic,
but the aspnet.webcontrols group is very quiet, and people here seem
more experienced:
I came across an irritating problem with the ASP.NET execution model
about which I've seen several people ask questions but have seen few
good answers.
The exact details are not really important, but to give you an idea, I
need to provide a set of arbitrary page designs associated with
particular combinations of entries in a directory structure. As the user
browses the directory structure (various ways of slicing a market sector
segmentation model) they will be presented with pages which either show
a default web page or else specific content. The layout and content is
user-configurable and is stored in the database and retrieved with the
home page object.
There's a directory browser control which manages the navigation and
maintains some session state (basically encapsulates an object
containing a hashtable of available dimension lists and a stack of
selected ones). It raises an event when the current directory path
changes, passing a specification object which is picked up by the page.
The page then uses that to obtain a MarketSectorHomePage.
The MarketSectorHomePage is exposed by the page via an interface, and is
displayed by a home page control. So we have:
public class ViewMSHP : System.Web.UI.Page,
IMarketSectorHomePageHost{...}
where IMarketSectorHomePageHost is defined as:
public interface IMarketSectorHomePageHost
{
MarketSectorHomePage MarketSectorHomePage
{
get;
set;
}
}
The base class of the home page control (BaseMarketSectorControl)
accesses the interface in the page like so:
IMarketSectorHomePageHost host = this.Page as IMarketSectorHomePageHost;
and exposes the MarketSectorHomePage to derived classes through a
protected property.
In CreateChildControls the home page control then examines the
MarketSectorHomePage object's PageContents object which defines the
names of the controls and their row and column positions. It creates a
table, inserting table cells and populating them with custom controls
created by reflection from the names defined in page contents. The
controls may or may not themselves be derived from
BaseMarketSectorControl, depending on whether they need to access and
render information from the MarketSectorHomePage.
This model works nicely when the MarketSectorHomePage is not changing
between postbacks, however when used in the above scenario where a
postback is induced by the directory browser it falls over. The control
tree created by the homepage control is not the same one as present on
the previous call, ASPNET can't find the controls where it thinks they
should be, and blows up.
It occurs to me that the same sort of thing would happen in many
scenarios with a classic model-view-controller architecture (and this
is, if you squint, MVC-like with looser than usual coupling).
After much messing about, I found a neat but unsatisfying workaround;
insert two instances of the home page control at the same location in
the page. Set the visible property of one to true, the other to false.
In OnPreRender, toggle the Visible property. Thus neither control is
visible both before and after a postback. If it isn't visible, it isn't
rendered, CreateChildControls doesn't run, everything works.
It works, but I wonder whether anyone has found a better way of dealing
with it?
--
Steve Walker