Nel pacchetto di controlli AjaxControlToolkit è presente il CollapsiblePanelExtender che presente alcuni problemi nel mantenimento dello stato della proprietà Collapsed. In rete sono presenti alcune soluzione che non mi hanno davvero convinto.
Il controllo usa una campo hidden in cui in fase di postback viene inviato lo stato della proprietà Collapsed così come l'utente lo ha lasciato sulla pagina prima di fare post del form in modo che il controllo possa mantenere lo stato del client tra un postback e un altro. Il nome di tale campo di supporto è il suo UniqueID + "_ClientState". Lo UniqueID sembra variare ad ogni richiesta - non ho analizzato il controllo con reflection ma posso pensare che lo UniqueID viene ricalcolato con il supporto di un GuiId ad ogni creazione del controllo.
L'ispirazione per la soluzione finale per risolvere il problema l'ho avuto analizzando quando detta nella discussione "CollapsiblePanelExtender inside user control not remembering its client state" e quanto scritto in "Setting a CollapsiblePanelExtender state from CodeBehind". Ho quindi incapsulato il controllo CollapsiblePanelExtender in un WebControl in cui trova la compagnia di altri controlli di supporto... in particolare di un HiddenField in cui verrà salvato lo UniqueID prima della fase di Render del controllo e della sua distruzione. Riporto il codice dei metodi OnLoad e OnPreRender che risolvono i problemi del CollapsiblePanelExtender.
private CollapsiblePanelExtender collapsiblePanelExtender;
private HiddenField hcpeUniqueId;
//...
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
/// </summary>
/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
protected override void OnLoad(EventArgs e)
{
if (Page.IsPostBack)
{
string clientState_FormName = string.Concat(hcpeUniqueId.Value, "_ClientState");
string clientState_FormValue = this.Page.Request.Form[clientState_FormName];
collapsiblePanelExtender.Collapsed = clientState_FormValue == "true";
}
base.OnLoad(e);
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
protected override void OnPreRender(EventArgs e)
{
collapsiblePanelExtender.ClientState = collapsiblePanelExtender.Collapsed ? "true" : "false";
hcpeUniqueId.Value = collapsiblePanelExtender.UniqueID;
base.OnPreRender(e);
}
oO0( ...purtroppo qualche controllo esce con il buco! )
posted @ giovedì 15 gennaio 2009 00:12