Frage

Ich habe dem Artikel gefolgt Trully Understanding ViewState (Großartiger Artikel übrigens) und die Bevölkerung meiner Dropdown -Liste funktioniert großartig. Ich habe sogar ein OnelectedInchange -Event eingerichtet, das fast genauso großartig feuert.

Das Problem, das ich gefunden habe, ist das ausgewählte Ereignis, das bei der Auswahl des 0. Index nicht ausfängt. Es tut jedoch alle anderen Zeiten.

Hier ist ein Code:

<asp:DropDownList runat="server" ID="DropDownList1" EnableViewState="false" 
AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" />


protected override void OnInit(EventArgs e)
{
    this.DropDownList1.DataTextField = "Text";
    this.DropDownList1.DataValueField = "Value";
    this.DropDownList1.DataSource = fillQueueDropDown();
    this.DropDownList1.DataBind();

    base.OnInit(e);
}

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    OnSelectedQueueChanged(e);
}

public void OnSelectedQueueChanged(EventArgs e)
    {
        // Do stuff.
    }

public event EventHandler queueNamesChangedEvent;
public void OnSelectedQueueChanged(EventArgs e)
    {
        if (queueNamesChangedEvent != null)
            queueNamesChangedEvent(this, e);
    }

Ich nehme an, ich kann in der Methode Page_load eine Art von Check durchführen:

  if(ViewState["selectedIndexChangedFlag"] != 1)
      // raise OnSelectedChange event

Oder gibt es etwas, das ich in der Oninit () -Methode einrichten kann, bei der ich diese Daten jedes Mal wieder aufrechte, wenn ich es kann?

Siehe, mein benutzerdefinierter EventHander wirft ein Ereignis an, das von einer übergeordneten Seite erfasst wird, auf der sich diese Kontrolle befindet, damit die Eltern mit dem neu ausgewählten Wert etwas Maßnahmen ergreifen können. Dies funktioniert derzeit für alle Fälle, in denen der ausgewählte Index> 0.

Ich erstelle eine Eigenschaft in diesem Steuerelement, die den zuletzt ausgewählten Index enthält. In diesem Fall kann meine übergeordnete Seite auf diesem Eigenschaftswert auf jedem Page_Load ... keine Aktion handeln.

Offen für Vorschläge. Oder wie dieses ausgewählte Ereignis für diese 0. Indexauswahl zum Feuer erzwingen.

War es hilfreich?

Lösung 2

Mein Ziel bei der Deaktivierung des ViewState auf dieser Dropdown -Liste ist es, die Größe des ViewState für die Seite zu minimieren.

Das Problem, das ich hatte, wenn ich nur das if (! Page.ispostback) {... DataBind () ...} gemacht habe, ist, dass meine Dropdown -Liste leer wird, wenn Sie zum ersten Mal ein Element auswählen und die Seite neu lädt, meine Dropdown -Liste wird leer .

Am Ende habe ich eine andere Eigenschaft für diese Kontrolle, lastIndex, erstellt. Wenn das aufgewählte Ereignis feuert, aktualisiere ich den letzten Wert. In der Seite page_load vergleiche ich die aktuellen und letzten Indexwerte, wenn sie unterschiedlich sind, und dann einen Index geändert.

    public int SelectedValue{
        get { return this.DropDownList1.SelectedItem.Value; }
    }

    public int LastIndex{
        get { return this.ViewState["lastIndex"] == null ? -1 : (int)this.ViewState["lastIndex"]; }
        set { this.ViewState["lastIndex"] = value; }
    }

    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        this.DropDownList1.DataTextField = "Text";
        this.DropDownList1.DataValueField = "Value";
        this.DropDownList1.DataSource = fillQueueDropDown();
        this.DropDownList1.DataBind();
    }

    protected void Page_Load(object sender, EventArgs e){
        if (this.LastIndex != this.SelectedValue)
            this.OnSelectedQueueChanged(new EventArgs());
    }

    private ListItemCollection fillQueueDropDown(){...}

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e){
        OnSelectedQueueChanged(e);
        this.LastIndex = this.SelectedValue;
    }

    public event EventHandler queueNamesChangedEvent;
    public void OnSelectedQueueChanged(EventArgs e){
        if (queueNamesChangedEvent != null)
            queueNamesChangedEvent(this, e);
    }

Sie haben aber recht. Die Daten werden in der Oninit-Phase neu beladen und neu begründet. Dann wird der ViewState wiederhergestellt (und wenn der 0. Index wiederhergestellt ist), erkennt die Steuerung die Änderung nicht.

Ich bin mir nicht sicher, ob dies der eleganteste Weg ist, aber es funktioniert bisher gut.

Dann fand ich dies in den MSDN -Dokumenten für Ipostbackdatahandler:

  public virtual bool LoadPostData(string postDataKey, 
     NameValueCollection postCollection) {

     String presentValue = Text;
     String postedValue = postCollection[postDataKey];

     if (presentValue == null || !presentValue.Equals(postedValue)) {
        Text = postedValue;
        return true;
     }

     return false;
  }

Da der Barwert der geänderte Wert entspricht, wird das Ereignis nicht abgefeuert.

Andere Tipps

Das Problem ist, dass Sie die Daten jedes Mal laden und dies den ausgewählten Index zurückzeigt. Stellen Sie sich vor, dies ist Ihr Dropdown:

zero [selected]
one
two

Dann ändern Sie im Client den ausgewählten Index:

zero
one [selected]
two

Dies bevölkert den versteckten Eingang __EVENTARGUMENT mit Ihrem neuen Index (1) und der versteckten Eingabe __EVENTTARGET mit dem id von Ihrer Dropdown. Jetzt tritt der serverseitige Code an und lädt Ihre Daten neu:

zero [selected]
one
two

"Null" ist der ausgewählte Wert, da dies der Standard ist, wenn die Daten geladen werden. Dann sucht ASP.net nach __EVENTTARGET und __EVENTARGUMENT in dem Request und findet Ihre Dropdowns id und findet den neuen Index (1). Jetzt sieht Ihr Dropdown so aus:

zero 
one [selected]
two

Da sich der Index verändert hat, erhöht der Dropdown seine SelectedIndexChanged Ereignis angibt, dass sich der Index geändert hat. Offensichtlich ist dies der Teil, der funktioniert. Lassen Sie uns nun sehen, warum die Auswahl des ersten Elements in der Liste das Ereignis nicht erhöht.

Nehmen wir nun an, wir haben immer noch den Dropdown in dem Staat, in dem es sich gerade befand (wobei "eins" ausgewählt und der ausgewählte Index von 1). Was passiert, wenn wir das erste Element in der Liste im Client auswählen?

__EVENTTARGET und __EVENTARGUMENT sind mit dem bevölkert id des Dropdowns und des neuen Index (0). Dann lädt der Server die Daten in den Dropdown und der Dropdown sieht jetzt wieder so aus:

zero [selected]
one
two

Beachten Sie das, da Sie die Daten neu geladen haben Vor Die Ereignisse, die der Index abgefeuert haben, ist bereits auf 0 gesetzt, da dies der Standard ist. Wenn Ihr Ereignis nun feuert und der ausgewählte Index des Dropdowns auf 0 gesetzt ist, sieht der Dropdown nicht als Änderung an, da sich der ausgewählte Index (soweit er weiß) nicht geändert hat.

Hier erfahren Sie, wie Sie das Problem beheben können:

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

    if (!Page.IsPostBack)
    {
        this.DropDownList1.DataTextField = "Text";
        this.DropDownList1.DataValueField = "Value";
        this.DropDownList1.DataSource = fillQueueDropDown();
        this.DropDownList1.DataBind();
    }    
}

Dies wird nur die Daten in den Dropdown -Bereich geladen, wenn die Seite kein Postback ist. Dies bedeutet, dass ViewState die Daten für Sie sowie den ausgewählten Index beibehält, sodass der Dropdown den neuen Index mit dem im Client gesehenen Index verglichen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top