2013-08-06 7 views
9

Wenn ich auf meiner Seite setzen: EnableViewState="true" ViewStateMode="Disabled" - Dann - das Viewstate ist für die Seite deaktivieren (wenn nicht überschreibt ...)Warum verlässt sich DropDownList.SelectedValue auf viewstate?

Dann ab zu lesen versuchen (die Steuerung unter der Annahme hat in den letzten besiedelt Dump auf dem Bildschirm und ein Wert gewählt):

MyDDL.SelectedValue ergeben wird ""

, dass wegen der behinderten Ansichtszustand ist:

Aber meine Frage ist auf einer höheren Ebene:

  • Wenn es nur um einen Formwert ist (was ich kann immer noch von Request.Form[MyDDL.UniqueID] bekommen) - und wir reden über einen Eingang, der etwas braucht nicht zu retten dessen Wert.

  • Warum hat die DropDownList benannte Eigenschaft (SelectedValue) auf Viewstate verlassen Ist?

p.s. die TextBox onchangechangevent verlässt sich auf Viewstate, obwohl das Steuerelement eine Eingabe ist (die Viewstate nicht benötigt) - es speichert den Wert des Textes und dann vergleicht es beim Postback.Aber es stützt sich nur auf Viewstate, wenn Sie onchange Ereignis (und Autopostback)

+0

Gut Textbox Wert nicht auf Viewstate verlassen Sie Viewstate deaktivieren können und Sie erhalten noch Textfeld Wert, Sein Wert kommt von IPostBackDataHandler. Request.Form [""] Funktioniert nur, wenn Sie Ihre Daten mit der POST-Methode übermitteln. Stellen Sie sich vor, ein Benutzer kann ein Formular aufgrund von Validierungsfehlern oder Fehlern nicht senden Holen Sie sich Ihre Werte von Request.Form [""]. –

+0

@surajsingh Das weiß ich schon. immer noch meine Frage bleibt. –

+0

Hoffe, ich bin jetzt auf dem richtigen Weg, ich habe nur eine Dropdown-Liste mit Listenelementen erstellt und es behält den Status auch nach der Deaktivierung von ViewState. Ich muss immer noch nach Drop-downs suchen, die über Datenbanktabellen begrenzt sind. Mal sehen, ob sie ihren Status behalten und ob ich eine Antwort bekomme. –

Antwort

6

Zusammenfassung: Wenn Sie die Kontrolle zu arbeiten, ohne Viewstate wollen, müssen Sie die Items-Auflistung auf jedem Postback bevölkern/binden. Ich empfehle, es im Page_Init-Ereignis (d. H. OnInit-Methode) zu tun.

Zunächst einmal, ich das diesen tollen Artikel immer empfehlen: TRULY Understanding ViewState.

Die SelectedValue Viewstate nicht erforderlich. Mit Blick auf den Code für List, die Dropdownlist von erbt, sehen wir den Code:

public virtual string SelectedValue 
{ 
    get 
    { 
    int selectedIndex = this.SelectedIndex; 
    if (selectedIndex >= 0) 
     return this.Items[selectedIndex].Value; 
    else 
     return string.Empty; 
    } 

Das Wichtigste aus diesem Code zu nehmen ist, dass die Liste Artikel aufgefüllt werden müssen SelectedValue zu bekommen.

Wenn Sie ViewState verwenden, ist die Items-Auflistung in ViewState beibehalten/geladen, wodurch die SelectedValue-Eigenschaft ohne erneute Bindung des Steuerelements funktioniert.

+0

So wie es funktioniert. (die Implementierung von SelectedValue ....) cool. (Denn es ist komisch, auf ViewState angewiesen zu sein, wenn ich nur den Wert brauche ....) –

7

die SelectedValue beruht auf ViewState weil beim Postback es seine ListItems vom ViewState umbaut und stellt dann den ausgewählten Wert auf der DropDownList vom Request Gegenstand.

Es wird nicht die Request Wert als SelectedValue direkt übernommen. Dies liegt wiederum daran, dass ASP.Net prüfen kann, ob der gepostete DropDownList nicht am Client manipuliert wurde. Dies geschieht, indem zuerst die ursprünglichen Artikel aus der ViewState deserialisiert werden. Es findet dann den Request Wert in den Elementen und legt seine Selected-Eigenschaft als true fest. Nur jetzt ist die SelectedValue Eigenschaft verfügbar. (oder SelectedIndex für diese Angelegenheit). Es sollte nun möglich sein, ein SelectedIndexChanged Ereignis auszulösen.

Dies ist auch der Grund, dass Sie die DropDownList nicht erneut in PageLoad binden müssen. Die Listenelemente werden automatisch von der ViewState entfernt.

Wenn die ViewState deaktiviert ist, dann wird es keine ursprünglichen Listenelemente in der ViewState geben und wird leer sein. Daher ist es nicht möglich, einen Gegenstand als ausgewählt zu markieren. Daher wird SelectedValue 0 sein oder SelectedItem wird null sein. Ich denke, das Ereignis SelectedIndexChanged wird auch nicht ausgelöst. Damit Dinge in diesem Fall funktionieren, muss eine Datenbindung erfolgen, vorzugsweise unter init.

Es gibt jedoch Problemumgehungen.

komplette Referenz: http://msdn.microsoft.com/en-us/library/ms972976.aspx

bearbeiten: (nach Op Kommentare)

Lebenszyklus der Seite verfolgt zu sehen, wo SelectedValue auf ViewState beruht:

Stufe 1 Init: Die Steuerung Hierarchy ist gebaut. Wenn die DropDownList hier gebunden ist oder die ListItems deklarativ hinzugefügt wurden, wird die Liste hier eingetragen.

Phase 2 Load ViewState: Bei PostBack wird der ViewState hier validiert und in die DropDownList geladen. Es gibt keineSelectedValue hier.

Stufe 3 Lastpostback Daten: Hier wird der Request Wert (aus dem Formular Anfrage) entnommen und dann auf die Steuerung angewendet. In diesem Fall von DropDownList es jetzt Sets die SelectedValue aus dem empfangenen Request Objektwert, interne Implementierung so etwas wie diese:

string selectedValue = HttpContext.Current.Request.Form[DropDownList_Id]; 
Items.FindByValue(selectedValue).Selected = true; 

Was hier wichtig ist, ist, dass, wenn Viewstate nicht da ist und nicht Dropdown Daten- ist gebunden, dann ist die ListItem-Auflistung leer und daher SelectedValue Eigenschaft ist 0. Das hat nichts mit interner Implementierung einer Eigenschaft zu tun.

Wenn der ViewState nicht vorhanden ist (deaktiviert) und DropDownList datengebunden ist, dann wird die ListItem-Auflistung vorhanden sein und das entsprechende Element wird als ausgewählt markiert. Daher gibt die SelectedValue-Eigenschaft den korrekten Wert zurück.

Wenn die Elementauflistung neu ist (durch eine erneute Bindung mit anderen Datensätzen oder ViewState wird ungültig gemacht), wird der Formularwert Request nicht in der Objektauflistung gefunden und wiederum SelectedValue ungültig.

Phase 4 Laden der Seite: Zu diesem Zeitpunkt wurden die Daten ViewState (oder Datenbindung) und PostBack bereits geladen.

Stufe 5 Raise Postbackereignis: In diesem Stadium des OnSelectedIndexChanged Fall Dropdown ausgelöst wird, wenn der Index in Stufe 3.

daher geändert wurde, stützt sich die SelectedValue auf Viewstate in Stufe 3. Natürlich, wenn Das Steuerelement ist in geeigneter Weise datengebunden. Dann wird es nicht auf ViewState als Korollar angewiesen.

SelectedValue verlässt sich auf ViewState, um sicherzustellen, dass die Objektauflistung vor dem Festlegen ausgefüllt wurde. Datenbindung/Neubindung ist nur eine weitere Möglichkeit, um sicherzustellen, dass die Elementauflistung gefüllt ist.

Hoffnung, die klärt.

+0

das manipulierte Problem wird mit validationMAc überprüft. es hat nichts mit selectedvalue zu tun. –

+0

_ Es kann kein Objekt als ausgewählt markiert werden, richtig. aber es sollte einen Wert (IMHO) wie die Anfrage haben.form –

+0

Haben Sie die Referenz gelesen, die ich oben verlinkt habe? – Abhitalks

0
 protected void Page_Load(object sender, EventArgs e) 
      { 
       (!Page.IsPostBack) 
       { 
        string qry = "SELECT TOP(5)xxx, xxxx FROM dbo.xxxxxx "; 
        DataSet ds = new DataSet(); 
        ds = SqlHelper.ExecInDS(qry); 
        drpDwn.DataSource = ds.Tables[0]; 
        drpDwn.DataValueField = Convert.ToString(ds.Tables[0].Columns["xxx"]); 
        drpDwn.DataTextField = Convert.ToString(ds.Tables[0].Columns["xxx"]);     
        drpDwn.DataBind(); 
       } 
       //Here You will get selected value from dropdown 
       string sss= Request.Form["drpDwn"]; 
    } 
0

Wenn Sie die Dropdown wollen, ohne Viewstate zu arbeiten, können Sie die Kontrolle in page_load binden nur einmal, wie unten angegeben:

 protected void Page_Load(object sender, EventArgs e) 
      {   
    //whatever you use declarative binding (in aspx page), or define data source here 
       if (!IsPostBack) 
       { 
        ddl.DataBind(); //fire databinding events and fill items, and selectedvalue has a value. 
       } 

       //you can get the selectedvalue 
       var sv=ddl.SelectedValue ; // 
      }   
  • Im Fall (Viewstate ist deaktiviert), Asp.net FrameWork Mit jedem PostBack die Artikel aus dem Backend abrufen.

  • Im Fall (Viewstate aktiviert ist), abrufen Asp.net FrameWork die Elemente aus der Viewstate ohne das hintere Ende mit jedem Postback zu schlagen

Normalerweise ist die Asp.net FrameWork die Daten Feuer Bindung Ereignisse in PreRender-Ereignis: Lesen Sie ASP.NET Page Life Cycle Overview

Sie können dieses Verhalten bestätigen, indem Sie Trace aktivieren.

SelectedValue ist nicht direkt auf ViewState von source code of ListControl angewiesen, ABER hängt von den oben beschriebenen Punkten ab.