Je construis un contrôle serveur personnalisé dérivé de CompositeControl
.
Le contrôle contient un certain nombre de contrôles enfants (Labels, DropDownList, ListSearchExtender, etc.). Tous résident à l'intérieur d'un UpdatePanel
.
Le contrôle publie également des événements. Pour cela, j'ai ajouté deux propriétés: EnableCallBacks et CallBacksAsPostBacks. Ces deux propriétés doivent configurer le comportement de publication du panneau de mise à jour.PostBackTrigger ajouté dynamiquement dans le contrôle de serveur personnalisé ne pas être rendu correctement
Des idées à quoi devrait ressembler une implémentation correcte?
Je reçois quelques problèmes avec la façon dont j'implémenté:
l'PostBackTrigger ne sont pas toujours rendus dans le code HTML de sortie.
Ayant à la fois à l'intérieur des méthodes
CreateChildControls
Triggers.Add(trigger)
etControls.Add(_updatePanel)
conduit à la PostBackTrigger toujours être rendu, même si je le supprimer plus tard (par exemple dans les RenderControl() ou PreRender()). Si je n'ajoute pas le trigger ici mais plus tard, il ne sera jamais rendu. A ce stade, je n'ai pas encore les valeurs correctes de toutes mes propriétés (par exempleEnableCallBacks
etCallBacksAsPostBacks
).Il est impossible de placer la déclaration de
Controls.Add(_updatePanel)
dans la RenderControl méthode en raison de son beeing trop tard pour AJAX (dernier istPreRender()
sinon je reçois une exception).Idéalement, je voudrais instancier tous les contrôles dans CreateChildControls(), puis définir leurs valeurs plus tard, par exemple. PreRender ou RenderControl
Avoir les deux déclarations dans la méthode des résultats dans
PreRender
, que le déclencheur se rend en fonction corretly mes paramètres dans la page contenant, mais je ne suis pas le DropDownList peuplé avec ses données du ViewState (sur appel/publication).
protected override void CreateChildControls()
{
base.CreateChildControls();
_updatePanel = new UpdatePanel();
_updatePanel.ID = "FprDropDownList_UpPnl";
_updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
_label = new FprLabel();
_label.ID = "FprDropDownList_Lbl";
_updatePanel.ContentTemplateContainer.Controls.Add(_label);
_dropDownList = new DropDownList();
_dropDownList.ID = "FprDropDownList_Ddl";
_dropDownList.CssClass = "fprDropDownList";
_dropDownList.AutoPostBack = true;
_updatePanel.ContentTemplateContainer.Controls.Add(_dropDownList);
_label.AssociatedControlID = _dropDownList.ClientID;
_listSearchExtender = new ListSearchExtender();
_listSearchExtender.ID = "FprDropDownList_Lse";
_listSearchExtender.TargetControlID = _dropDownList.ClientID;
_listSearchExtender.PromptPosition = ListSearchPromtPosition;
_listSearchExtender.PromptCssClass = "fprListSearchExtender";
_updatePanel.ContentTemplateContainer.Controls.Add(_listSearchExtender);
_ddlPostBackTrigger = new PostBackTrigger();
_ddlPostBackTrigger.ControlID = _dropDownList.ClientID;
//_updatePanel.Triggers.Add(_ddlPostBackTrigger);
Controls.Add(_updatePanel);
}
protected override void OnPreRender(EventArgs pE)
{
if (EnableCallBacks)
{
_dropDownList.SelectedIndexChanged += DropDownList_SelectedIndexChanged;
}
if (EnableCallBacks && CallBacksAsPostBacks)
{
_updatePanel.Triggers.Add(_ddlPostBackTrigger);
}
//Controls.Add(_updatePanel);
base.OnPreRender(pE);
}
public override void RenderControl(HtmlTextWriter pWriter)
{
// Do some things... like set Enable-state of child controls
base.RenderControl(pWriter);
}