代码之家  ›  专栏  ›  技术社区  ›  scottm

如何以编程方式向ASP.NET更新面板添加触发器?

  •  4
  • scottm  · 技术社区  · 14 年前

    我正在尝试编写一个报价生成器。对于每个产品,都有一组选项。我想为每个选项动态添加一个下拉列表,然后将它们的selectedIndexChanged事件全部连接起来以更新报价成本。

    我在向更新面板添加DropDownList控件时没有遇到任何问题,但似乎无法连接事件。

    页面加载后,下拉列表中包含了它们的数据,但是更改它们不会调用SelectedIndexChanged事件处理程序,QuoteUpdatePanel也不会更新。 我有这样的东西:

    编辑: 自从 programmatically adding AsyncPostBackTrigger controls is not supported ,我已将我的代码更改为此,但仍无法获取事件:

    编辑2: 尝试添加占位符以将下拉列表添加到(而不是直接添加到ContentTemplateContainer中),但仍然没有触发任何事件。

    四分音符

    <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 回复  |  直到 14 年前
        1
  •  4
  •   Oleks    14 年前

    Afaik,将异步触发器添加到 UpdatePanel 以编程方式控制正在工作。

    解决方法是将它们添加到 Page_Init 事件和设置触发器 ControlID 控件唯一ID值的属性:

    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 像个魔咒一样工作(直到页面的初始事件)。

    我是这样做的:

    报价属性控制.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();
    }
    

    报价属性控制.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>
    

    Abx.CS

    string[] names = { "ab", "bc", "ef" };
    
    protected void Page_Init(object sender, EventArgs e)
    {
        ctlQuoteProperty.PopluateUpdatePanel(names);
    }
    

    阿斯克斯

    <%@ 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>