Я создаю пользовательский серверный элемент управления, полученный из CompositeControl
.
Элемент управления содержит несколько дочерних элементов управления (Labels, DropDownList, ListSearchExtender и т. Д.).Все они находятся внутри UpdatePanel
.
Элемент управления также публикует события.Для этого я добавил два свойства: EnableCallBacks и CallBacksAsPostBacks.Эти два свойства должны настраивать поведение обратной передачи на панели обновления.
Есть идеи, как должна выглядеть правильная реализация?
У меня возникают некоторые проблемы с тем, как я реализовал это:
PostBackTrigger не всегда отображается в выходном html.
Наличие как Triggers.Add(trigger)
, так и Controls.Add(_updatePanel)
внутри отведений методов CreateChildControls
чтобы PostBackTrigger всегда отображался, даже если я удалю его позже (например, в RenderControl () или PreRender ()).Если я не добавлю триггер здесь, но позже, то он никогда не будет обработан.На данном этапе у меня пока нет правильных значений всех моих свойств (например, EnableCallBacks
и CallBacksAsPostBacks
).
Невозможно разместить оператор Controls.Add(_updatePanel)
внутри RenderControl-метода из-за того, что он слишком поздно для AJAX (последний ist PreRender()
в противном случае я получаю исключение).
В идеале я бы создал все элементы управления в CreateChildControls (), а затемустановите их значения позже, например, в PreRender или RenderControl
Наличие обоих операторов в методе PreRender
приводит к тому, что триггер корректно отображается в зависимости от моих настроек на содержащей странице, ноЯ не получаю DropDownList, заполненный его данными из ViewState (при вызове / обратной передаче).
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);
}