Как программно добавить триггеры в ASP.NET UpdatePanel? - PullRequest
4 голосов
/ 26 апреля 2010

Я пытаюсь написать генератор цитат. Для каждого товара есть набор опций. Я хочу динамически добавить раскрывающийся список для каждого параметра, а затем настроить все события SelectedIndexChanged, чтобы обновить стоимость котировки.

У меня нет проблем с добавлением элементов управления DropDownList к моей UpdatePanel, но я не могу связать события.

После загрузки страницы есть раскрывающиеся списки с их данными, но их изменение не вызывает обработчик события SelectedIndexChanged и не обновляет QuoteUpdatePanel. У меня есть что-то вроде этого:

Редактировать: Поскольку программное добавление элементов управления AsyncPostBackTrigger не поддерживается , я изменил свой код на это, но я все еще не получаю событие:

Редактировать 2: Попытка добавления PlaceHolder для добавления раскрывающихся списков (вместо этого непосредственно в ContentTemplateContainer, по-прежнему нет событий.

QuotePanel.ASCX

<asp:ScriptManager ID="ScriptManager" runat="server" />

<asp:UpdatePanel ID="QuoteUpdatePanel" runat="server" ChildrenAsTriggers="true">
    <ContentTemplate>
        Cost: <asp:Label ID="QuoteCostLabel" runat="server" />
        <fieldset id="standard-options">
            <legend>Standard Options</legend>
            <asp:UpdatePanel ID="StandardOptionsUpdatePanel" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
                <ContentTemplate>
                <asp:PlaceHolder ID="StandardOptionsPlaceHolder" runat="server" />                   
                </ContentTemplate>
            </asp:UpdatePanel>
        </fieldset>
    </ContentTemplate>
</asp:UpdatePanel>

Код для добавления выпадающих списков и события, к которому они подключаются:

protected void PopluateUpdatePanel(IEnumerable<IQuoteProperty> standardOptions)
{
    foreach (IQuoteProperty standardOp in standardOptions)
    {
        QuotePropertyDropDownList<IQuoteProperty> dropDownList = new QuotePropertyDropDownList<IQuoteProperty>(standardOp);
        dropDownList.SelectedIndexChanged += QuotePropertyDropDown_SelectedIndexChanged;
        dropDownList.ID = standardOp.GetType().Name + "DropDownList";
        dropDownList.CssClass = "quote-property-dropdownlist";

        Label propertyLabel = new Label() {Text = standardOp.Title, CssClass = "quote-property-label"};

        StandardOptionsPlaceHolder.Controls.Add(propertyLabel);
        StandardOptionsPlaceHolder.Controls.Add(dropDownList);

        _standardOptionsDropDownLists.Add(dropDownList);

        ScriptManager.RegisterAsyncPostBackControl(dropDownList);

    }

}

void QuotePropertyDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
    QuoteCostLabel.Text = QuoteCost.ToString();
    StandardOptionsUpdatePanel.Update();
}

1 Ответ

4 голосов
/ 27 апреля 2010

AFAIK, программно работает добавление асинхронных триггеров к элементу управления UpdatePanel.

Обходной путь - добавить их в событие Page_Init и установить для свойства ControlID триггера значение уникального идентификатора элемента управления:

AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
// unique id instead of client id
trigger.ControlID = yourDropDownControl.UniqueID;  
trigger.EventName = "SelectedIndexChanged"; 
QuoteUpdatePanel.Triggers.Add(trigger);

Кажется, сделал эту работу. Я создал похожую структуру страницы / управления выше. Таким образом, есть пользовательский элемент управления QuotePropertyControl и Default страница, которая содержит этот элемент управления.

Я добавил свойство dropDownList.AutoPostBack = true и смог отловить асинхронную обратную передачу из выпадающего списка. Итак, угадывание проблемы было в этом свойстве.

Еще одна вещь: действительно не имеет значения, как зарегистрировать асинхронный триггер; оба варианта ScriptManager.RegisterAsyncPostBackControl и AsyncPostBackTrigger работали как шарм (до события init страницы).

Вот как я это сделал:

QuotePropertyControl.ascx.cs

private string[] data = { "a", "b", "c", "d", "e" };

public void PopluateUpdatePanel(IEnumerable<string> standardOptions)
{
    foreach (string standardOp in standardOptions)
    {
        DropDownList dropDownList = new DropDownList();
        dropDownList.SelectedIndexChanged +=
            QuotePropertyDropDown_SelectedIndexChanged;
        dropDownList.ID = standardOp + "DropDownList";
        dropDownList.CssClass = "quote-property-dropdownlist";
        dropDownList.AutoPostBack = true;
        dropDownList.DataSource = data;
        dropDownList.DataBind();

        Label propertyLabel = new Label() { Text = standardOp };

        StandardOptionsPlaceHolder.Controls.Add(propertyLabel);
        StandardOptionsPlaceHolder.Controls.Add(dropDownList);

        ScriptManager.GetCurrent(Page)
            .RegisterAsyncPostBackControl(dropDownList);
    }
}

protected void QuotePropertyDropDown_SelectedIndexChanged(
    object sender,
    EventArgs e
    )
{
    StandardOptionsUpdatePanel.Update();
}

QuotePropertyControl.ascx

<asp:UpdatePanel ID="QuoteUpdatePanel" runat="server" ChildrenAsTriggers="true">
    <ContentTemplate>
        Cost:
        <asp:Label ID="QuoteCostLabel" runat="server" />
        <fieldset id="standard-options">
            <legend>Standard Options</legend>
            <asp:UpdatePanel ID="StandardOptionsUpdatePanel" 
                runat="server" 
                ChildrenAsTriggers="true" 
                UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:PlaceHolder ID="StandardOptionsPlaceHolder" 
                    runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </fieldset>
    </ContentTemplate>
</asp:UpdatePanel>

Default.aspx.cs

string[] names = { "ab", "bc", "ef" };

protected void Page_Init(object sender, EventArgs e)
{
    ctlQuoteProperty.PopluateUpdatePanel(names);
}

Default.aspx

<%@ Register Src="~/QuotePropertyControl.ascx" 
             TagPrefix="uc" 
             TagName="QuoteProperty" %>

<form id="form1" runat="server">
<div>
    <asp:ScriptManager ID="ScriptManager" runat="server" />
    <uc:QuoteProperty runat="server"
        ID="ctlQuoteProperty">
    </uc:QuoteProperty>
</div>
</form>
...