views:

618

answers:

1

I am trying to write a quote generator. For each product, there are a set of options. I want to dynamically add a drop down list for each option, and then have their SelectedIndexChanged events all wired up to update the quote cost.

I am not having any trouble adding the DropDownList controls to my UpdatePanel, but I can't seem to wire up the events.

After the page loads, the drop downs are there, with their data, but changing them does not call the SelectedIndexChanged event handler, nor does the QuoteUpdatePanel update. I have something like this:

Edit: Since programmatically adding AsyncPostBackTrigger controls is not supported, I've change my code to this, but I still don't get the event:

Edit 2: Tried adding a PlaceHolder to add the drop down lists to (instead directly into the ContentTemplateContainer, still no events firing.

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>

The code to add the dropdowns and the event they are to be wire up for:

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  A: 
Alex
This is a separate user control. In the current implementation, I added the triggers in the QuotePanelControl_Init() event. After your suggestion, I made the PopulateUpdatePanel method public and called it from the Page's Init event. I still don't get any events.
scottm
@scottm: I'll try it on my side and report back the progress
Alex
That was the problem! thanks
scottm
Any idea why I can maintain the drop down list view state? It keeps changing back to default
scottm
Could you explain the problem with more details? It seems viewstate is loaded normally.
Alex
@Alex, When I change one of the drop down lists that is generated, after it updates the cost, it looks like the controls are being added over again (in QuotePanel_Init), and so the value is reset to whatever the default is.
scottm
@scottm, the controls should be added with each Page_Init (or so) event because after this the viewstate is being loaded into the controls. So it is important to add the same controls(with the same ids) as was being added before the postback has occured. If the controls don't change(as in example I provided in my answer: 3 dropdowns, the the same data, the same ids - after post back) the viewstate should be loaded into the controls. Try the example above, even after the postback the selected value won't be resetted to the default value.
Alex