it-swarm.com.de

ASP.NET/C #: DropDownList SelectedIndexChanged im Serversteuerelement wird nicht ausgelöst

Ich erstelle ein Serversteuerelement, das im Wesentlichen zwei Dropdown-Listen bindet, eine für Land und eine für Staat, und die Status-Dropdown-Liste für das vom Land ausgewählte Ereignis "indexchanged" aktualisiert. Es wird jedoch nicht zurückgeschickt. Irgendwelche Ideen warum? Bonuspunkte für das Einwickeln in ein UpdatePanel (mit Darstellungsproblemen; vielleicht, weil ich keine zu verweisende Seite habe?)

Hier ist was ich habe (mit ein paar Extras zum Datenzugriff):

public class StateProv : WebControl
{
    public string SelectedCountry;
    public string SelectedState;

    private DropDownList ddlCountries = new DropDownList();
    private DropDownList ddlStates = new DropDownList();

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        IList<Country> countries = GetCountryList();
        IList<State> states = new List<State>();

        if (SelectedCountry != null && SelectedCountry != "")
        {
            states = GetStateList(GetCountryByShortName(SelectedCountry).CountryShortName);
        }
        else
        {
            states.Add(new State { CountryId = 0, Id = 0, StateLabelName = "No states available", StateLongName = "No states available", StateShortName = "" });
        }

        ddlCountries.DataSource = countries;
        ddlCountries.DataTextField = "CountryLongName";
        ddlCountries.DataValueField = "CountryShortName";
        ddlCountries.SelectedIndexChanged += new EventHandler(ddlCountry_SelectedIndexChanged);
        ddlCountries.AutoPostBack = true;

        ddlStates.DataSource = states;
        ddlStates.DataTextField = "StateLongName";
        ddlStates.DataTextField = "StateShortName";

        ddlCountries.DataBind();
        ddlStates.DataBind();

        if (!string.IsNullOrEmpty(SelectedCountry))
        {
            ddlCountries.SelectedValue = SelectedCountry;

            if (!string.IsNullOrEmpty(SelectedState))
            {
                ddlStates.SelectedValue = SelectedState;
            }
        }            
    }


    protected override void RenderContents(HtmlTextWriter output)
    {
        ddlCountries.RenderControl(output);
        ddlStates.RenderControl(output);
    }

    private IList<Country> GetCountryList()
    {
        //return stuff
    }

    private IList<State> GetStateList(Country country)
    {
        //return stuff
    }

    private IList<State> GetStateList(string countryAbbrev)
    {
        Country country = GetCountryByShortName(countryAbbrev);
        return GetStateList(country);
    }

    private Country GetCountryByShortName(string countryAbbrev)
    {
        IList<Country> list = dataAccess.RetrieveQuery<Country>();
        //return stuff
    }

    private IList<State> GetAllStates()
    {
        //return stuff
    }

    protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e)
    {
        IList<State> states = GetStateList(GetCountryList()[((DropDownList)sender).SelectedIndex]);
        ddlStates.DataSource = states;
        ddlStates.DataBind();
    }
}

Bearbeiten: Viewstate befindet sich auf der Seite, und andere Steuerelemente auf der Seite führen Postbacks korrekt aus, nur nicht dies.

11
Jack Lawson

Ist Viewstate aktiviert?

Edit: Vielleicht sollten Sie es noch einmal überdenken, die Renderfunktion zu überschreiben

  protected override void RenderContents(HtmlTextWriter output)
    {
        ddlCountries.RenderControl(output);
        ddlStates.RenderControl(output);
    }

fügen Sie stattdessen die Dropdown-Listen zum Steuerelement hinzu und rendern Sie das Steuerelement mit den standardmäßigen RenderContents.

Edit: Siehe die Antwort von Dennis, auf die ich in meinem letzten Kommentar hingewiesen habe:

Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );
5
Chris Ballance

Ich kann nicht erkennen, dass Sie diese Steuerelemente der Steuerelementhierarchie hinzufügen. Versuchen Sie:

Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );

Ereignisse werden nur aufgerufen, wenn das Steuerelement Teil der Steuerelementhierarchie ist.

4
baretta

Sie müssen AutoPostBack für das Land DropDownList auf true setzen.

protected override void OnLoad(EventArgs e)
{
    // base stuff

    ddlCountries.AutoPostBack = true;

    // other stuff
}

Bearbeiten

Ich habe vermisst, dass du das getan hast. In diesem Fall müssen Sie überprüfen, ob ViewState aktiviert ist.

3
Garry Shutler

Ich hatte das gleiche Problem, konnte dieses Problem jedoch umgehen, indem AutoPostBack auf true gesetzt wurde. In einem Aktualisierungsfenster wurde der Auslöser auf die Dropdownlisten-Steuerelement-ID und der Ereignisname auf SelectedIndexChanged gesetzt, z.

    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always" enableViewState="true">
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="ddl1" EventName="SelectedIndexChanged" />
        </Triggers>
        <ContentTemplate>
            <asp:DropDownList ID="ddl1" runat="server" ClientIDMode="Static" OnSelectedIndexChanged="ddl1_SelectedIndexChanged" AutoPostBack="true" ViewStateMode="Enabled">
                <asp:ListItem Text="--Please select a item--" Value="0" />
            </asp:DropDownList>
        </ContentTemplate>
    </asp:UpdatePanel>
1
Wolexie

Zunächst möchte ich etwas klarstellen. Ist dies ein Beitrag zurück (Reise zurück zum Server), oder tritt er zurück, kommt er jedoch nie in den Ereignishandler ddlCountry_SelectedIndexChanged?

Ich bin nicht sicher, welchen Fall Sie haben, aber wenn es sich um den zweiten Fall handelt, kann ich Ihnen einen Vorschlag machen. Wenn es sich um den ersten Fall handelt, ist dies folgende:.

Für den zweiten Fall (der Event-Handler wird nie ausgelöst, obwohl die Anfrage gestellt wurde), sollten Sie die folgenden Vorschläge ausprobieren:

  1. Fragen Sie das Request.Params [ddlCountries.UniqueID] ab und prüfen Sie, ob es einen Wert hat. Ist dies der Fall, lösen Sie den Ereignishandler manuell aus.
  2. Solange der Ansichtsstatus aktiviert ist, binden Sie die Listendaten nur, wenn es sich nicht um einen Beitrag handelt.
  3. Wenn der Ansichtsstatus deaktiviert sein muss, setzen Sie die Listendatenbindung in OnInit anstelle von OnLoad.

Beachten Sie, dass beim Aufruf von Control.DataBind () die Ansichtsstatus- und Postback-Informationen nicht mehr vom Steuerelement verfügbar sind. Wenn der Ansichtsstatus aktiviert ist, werden die Werte der DropDownList zwischen dem Zurückschreiben beibehalten (die Liste wird nicht erneut gebunden). Wenn Sie eine andere DataBind in OnLoad ausgeben, werden die Statusdaten der Ansicht gelöscht, und das SelectedIndexChanged-Ereignis wird niemals ausgelöst.

Wenn der Ansichtsstatus deaktiviert ist, haben Sie keine andere Wahl, als die Liste jedes Mal erneut zu binden. Wenn ein Postback auftritt, gibt es interne ASP.NET-Aufrufe, um den Wert von Request.Params in die entsprechenden Steuerelemente aufzufüllen, und ich vermute, dass dies zu einem Zeitpunkt zwischen OnInit und OnLoad geschieht. In diesem Fall können Sie durch Wiederherstellen der Listenwerte in OnInit Ereignisse korrekt auslösen.

Vielen Dank für Ihre Zeit, die Sie hier lesen, und begrüßen Sie alle, wenn ich mich irre.

0