The June CTP of "Atlas" is out; I'd recommend downloading it if you're into that sort of thing.
The biggest change in the release is that you now have the ability to dynamically create and use UpdatePanel controls - this opens up the capability to use them in templated scenarios such as in GridViews, DataGrids, Repeaters, etc. The change the CTP made wasn't to "add" dynamic UpdatePanel controls, but to relax a constraint which pinched when Triggers had to reference the UpdatePanel.
Triggers are the feature of UpdatePanels which allows them to be connected to controls outside their content template region; that is, if the UpdatePanel surrounds a bunch of controls, but wants to also be "notified" when a control outside itself causes a post back, then it must use a Trigger (out of the box there are two types of triggers: those which update a panel when a control raises an event, and those which update a panel when a control's value changes). This is useful if you have a region that surrounds controls that must be asynchronously updated in the browser, but the control that causes the asynchronous update is off somewhere else on the page (such as a submit button, et al).
When the client "fires" the trigger, the posted data comes back asynchronously and is retrieved/analyzed on the server during the load post data event in the page's lifecycle - which just so happens to occur before the Load, PreRender, etc. events. When the posted data is recieved on the server, the code immediately attempts to link the posted data of the trigger to an UpdatePanel in memory. But - for many controls that support templates - this is too early for an UpdatePanel control which resides within them to have been instantiated. Therefore - no UpdatePanel is found and the post back results in no change on the client....this is the constraint that was changed.
Now, as of the June CTP, you can add UpdatePanel's dynamically to a page - which means they can be inserted at any time and can therefore be a part of the template of GridViews, etc. The most blatant change which powers this new ability occured in the RegisterUpdatePanel public method of the ScriptManager object - a method called by the OnInit method of the UpdatePanel to register itself with the ScriptManager. Whenever the UpdatePanel is instantiated on the page it must register itself with the ScriptManager so that post back events can be filtered to it proxy the ScriptManager (recall that the ScriptManager is basically the king of all controls on the page). What changed in this method is that it now references two variables which are set during the load post data phase of the page lifecycle by the ScriptManager as a "this is what happened during that phase" diary for UpdatePanels that may come about later.
The first of the two new variables referenced in the RegisterUpdatePanel method stores the unique identifier for the UpdatePanel sent to it by the client if that panel isn't found by the time the load post data event occurs. The second is a boolean flag which gets set to True when the load post data phase has completed to prevent duplicate operations on the control (double initializations). Here is the code:
public void RegisterUpdatePanel(UpdatePanel panel){ if (panel == null) { throw new ArgumentNullException("panel"); } if ((this._allUpdatePanels != null) && this._allUpdatePanels.Contains(panel)) { throw new ArgumentException("This UpdatePanel has already been registered.", "panel"); } if (this._allUpdatePanels == null) { this._allUpdatePanels = new List<UpdatePanel>(); } this._allUpdatePanels.Add(panel); if ((this._updatePanelRequiresUpdate != null) && (panel.UniqueID == this._updatePanelRequiresUpdate)) { if (panel.Mode == UpdatePanelMode.Conditional) { panel.Update(); } this._updatePanelRequiresUpdate = null; } if (this._panelsInitialized) { panel.Initialize(); }}
When the load post data phase has completed, and the update panel which caused the post back event on the client wasn't found, the _updatePanelRequiresUpdate variable is set to the unique id - in addition the _panelsInitialized boolean is set to true. When an UpdatePanel is instantiated dynamically at a later time, its OnInit method will be called by the page framework (when you add a control to a control collection, one of the operations done to the control is to have its OnInit method called since it wasn't around when the whole page trickled the event down to its child controls). The UpdatePanel's OnInit method calls RegisterUpdatePanel, which now has the unique identifier of the newly instantiated panel control to check against the _updatePanelRequiresUpdate variable. If the identifiers match and this new control's mode is conditional, then the panel is explicitly updated. Regardless, if the Initialize method was called for all early panel's on the page already, then the newly instantiated control has it's Initialize method called thanks to the _panelsInitialized boolean.
As a result...dynamically created UpdatePanels are now possible.
Remember Me
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.