I have three dropdownlists, three cascadingdropdown extenders, and updatepanel within a repeater. I need to update a label control inside of the updatepanel when the selectedindexchanged event fires for the last dropdown. The problem I'm having is that the event doesn't seem to fire the first time the selectedindex is changed. It works as expected after changing the first time. Anyone have any ideas as to why this is happening. Here is my code.
<asp:RepeaterID="uxPublicationRepeater"OnItemDataBound="PublicationRepeater_ItemDataBound"OnItemCommand="Pub_ItemCommand"runat="server">
<ItemTemplate>
<ajax:CascadingDropDownID="uxPublicationCascading"runat="server"Category="Publication"
ServiceMethod="GetPublicationsByMarket"TargetControlID="uxPubDropDownList"
ParentControlID="uxMarketDropDownList"PromptText="Select.."LoadingText="Loading.."/>
<ajax:CascadingDropDownID="uxPublicationYearCascading"runat="server"
Category="PublicationYear"PromptText="Select.."LoadingText="Loading.."
ServicePath="~/Services/LookupWebService.asmx"ServiceMethod="GetYearsByPublication"
TargetControlID="uxPublicationDateDropDownList"ParentControlID="uxPubDropDownList"/>
<asp:DropDownListID="uxMarketDropDownList"runat="server"/>
<asp:DropDownListID="uxPubDropDownList"runat="server"/>
<asp:DropDownListID="uxPublicationDateDropDownList"OnSelectedIndexChanged="IndexChanged"AutoPostBack="true"runat="server"/>
<asp:UpdatePanelID="uxUpdatePanel"ChildrenAsTriggers="false"UpdateMode="conditional"runat="server">
<ContentTemplate>
<asp:LabelID="uxLabel"runat="server"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTriggerControlID="uxPublicationDateDropDownList"EventName="SelectedIndexChanged"/>
</Triggers>
</asp:UpdatePanel></ItemTemplate>
</asp:Repeater>
Thanks for the help.
Have you taken a look at the sample?http://www.asp.net/AJAX/Control-Toolkit/Live/CascadingDropDown/CascadingDropDown.aspx
This could be related to EventValidation (see http://www.asp.net/AJAX/Control-Toolkit/Live/Walkthrough/CCDWithDB.aspx specfically:"Finally, in order for the values to be submitted, EventValidation needs to be disabled for the page. EventValidation ensures that the values in each control match the values that were present when the page was rendered, but since these drop downs are populating on the client side, this is never true.")
-Damien
I tried turning event validation off and still no good. The event fires the first time if the controls are outside of the repeater, but doens't fire until the second time when inside the repeater.
No one else has ran into this problem? If I take the cascadingdropdown extender out, the events fire correctly. Just to recap, dropdownlists in a repeater, selectedindexchange event fires correctly. Dropdownlists and cascadingdropdown extenders inside a repeater the event doesn't fire until the second time the selectedindex is changed. If anyone is interested I have a small sample app that illustrates the problem.
c.barnes01:
No one else has ran into this problem? If I take the cascadingdropdown extender out, the events fire correctly. Just to recap, dropdownlists in a repeater, selectedindexchange event fires correctly. Dropdownlists and cascadingdropdown extenders inside a repeater the event doesn't fire until the second time the selectedindex is changed. If anyone is interested I have a small sample app that illustrates the problem.
Hi,
I'd like to see your small sample, it will be preferred to use NorthWind database or a fake data source built in code.
Here is a small app that illustrates the problem.
<%@. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" EnableEventValidation="false" Inherits="_Default" %><%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:Repeater ID="uxTestRepeater" OnItemDataBound="Repeater_DataBound" runat="server"> <ItemTemplate> <cc1:CascadingDropDown ID="uxCountriesCascading" Category="Countries" runat="server" ParentControlID="uxCountryDropDownList" TargetControlID="uxStatesDropDownList" LoadingText="Loading.." PromptText="Select.." ServiceMethod="GetScopedStates" /> <asp:DropDownList ID="uxCountryDropDownList" runat="server" /> <asp:DropDownList ID="uxStatesDropDownList" AutoPostBack="true" OnSelectedIndexChanged="SelectedIndex_Changed" runat="server" /><br /> <asp:UpdatePanel ID="uxUpdatePanel" runat="server"> <ContentTemplate> <asp:Label ID="uxStateLabel" runat="server" Text="Select a State" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="uxStatesDropDownList" EventName="SelectedIndexChanged" /> </Triggers> </asp:UpdatePanel> <hr /> </ItemTemplate> </asp:Repeater> </div> </form></body></html>
using System;using System.Collections;using System.Collections.Generic;using System.Collections.Specialized;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.Services;using System.Web.Script.Services;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using AjaxControlToolkit;public partialclass _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e) {if (!Page.IsPostBack) {this.uxTestRepeater.DataSource = GenerateRepeaterDataSource();this.uxTestRepeater.DataBind(); } }private List GenerateRepeaterDataSource() { List toReturn =new List(); toReturn.Add(new MyClass(1,"Chris"));return toReturn; }protected void Repeater_DataBound(object sender, RepeaterItemEventArgs e) { DropDownList countryDropDownList = e.Item.FindControl("uxCountryDropDownList")as DropDownList; countryDropDownList.DataSource = GenerateCountries(); countryDropDownList.DataTextField ="Value"; countryDropDownList.DataValueField ="Key"; countryDropDownList.DataBind(); }private Dictionary<int,string> GenerateCountries() { Dictionary<int,string> toReturn =new Dictionary<int,string>(); toReturn.Add(1,"USA"); toReturn.Add(2,"Canada"); toReturn.Add(3,"Mexico");return toReturn; }protected void SelectedIndex_Changed(object sender, EventArgs e) { DropDownList stateDropDown = senderas DropDownList; Label stateLabel = stateDropDown.NamingContainer.FindControl("uxStateLabel")as Label; stateLabel.Text = stateDropDown.SelectedItem.Text; } [WebMethod] [ScriptMethod]public static CascadingDropDownNameValue[] GetScopedStates(string knownCategoryValues,string category) { CascadingDropDownNameValue[] toReturn =null; StringDictionary values = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);if (values.Count == 1) {string key = values["undefined"];switch (key) {case"1": toReturn = GetStatesForUsa();break;case"2": toReturn = GetStatesForCanada();break;case"3": toReturn = GetStatesForMexico();break;default:break; } }return toReturn; }public static CascadingDropDownNameValue[] GetStatesForUsa() { CascadingDropDownNameValue[] toReturn =null; toReturn =new CascadingDropDownNameValue[5]; toReturn[0] =new CascadingDropDownNameValue("SC","1"); toReturn[1] =new CascadingDropDownNameValue("GA","2"); toReturn[2] =new CascadingDropDownNameValue("NY","3"); toReturn[3] =new CascadingDropDownNameValue("FL","4"); toReturn[4] =new CascadingDropDownNameValue("NC","5");return toReturn; }public static CascadingDropDownNameValue[] GetStatesForCanada() { CascadingDropDownNameValue[] toReturn =null; toReturn =new CascadingDropDownNameValue[5]; toReturn[0] =new CascadingDropDownNameValue("Saskatchewan","1"); toReturn[1] =new CascadingDropDownNameValue("Alberta","2"); toReturn[2] =new CascadingDropDownNameValue("British Columbia","3"); toReturn[3] =new CascadingDropDownNameValue("Nunavut","4"); toReturn[4] =new CascadingDropDownNameValue("Yukon","5");return toReturn; }public static CascadingDropDownNameValue[] GetStatesForMexico() { CascadingDropDownNameValue[] toReturn =null; toReturn =new CascadingDropDownNameValue[5]; toReturn[0] =new CascadingDropDownNameValue("Hidalgo","1"); toReturn[1] =new CascadingDropDownNameValue("Veracruz","2"); toReturn[2] =new CascadingDropDownNameValue("Puebla","3"); toReturn[3] =new CascadingDropDownNameValue("Durango","4"); toReturn[4] =new CascadingDropDownNameValue("Sonora","5");return toReturn; }}public class MyClass{private int id;public int ID {get {return id; }set { id =value; } }private string name;public string Name {get {return name; }set { name =value; } }public MyClass(int id,string name) {this.id = id;this.name = name; }}
I still haven't found a solution to this yet. Anyone have any suggestions?
Thanks
Bump
What is the full type name of the toReturn( List toReturn =new List();) object?
It should have been, List<MyClass> toReturn = new List<MyClass>();
thanks
I looked into it through, and found out that the reason is because the items are filled on client side.
1. On the first request( when isPostback is false ), there is no items in DDLState.
2. DDLState is filled when the page has been rendered in the browser
3. Select an item in the DDL to start a postback
4. The DDL tries to find the currentIndex( it's -1 since it can't be found ) and compares it with previousIndex( it's -1 since there is no item previously ) to see if a selectedChanged event should be fired. And it won't be fired because they are equal
5. On the second request, the previously posted item is kept in ViewState and subsequently added into DDLState's items collection
6. The previously index is 0 because the only item currently in DDLState matches the previous value. And currently posted item's value still doesn't exist, so currentIndex is -1. They are not equal, thus the SelectedIndexChanged event is fired.
Thanks for looking into the problem. It's weird that it works when not in a repeater.
No comments:
Post a Comment