2016-08-03 75 views
3

ein LinkButton-, Calendar- oder WizardStep-Steuerelement vorhanden ist. Ich habe ein Problem mit __doPostBack festgestellt und eine Lösung gefunden. Ich suche eine Erklärung für die Ursache und/oder eine bessere Lösung als meine Arbeit.__doPostBack funktioniert nur, wenn auf der Seite

Szenario: Ich habe ein Dropdown mit den Werten gefüllt; "-Auswählen-", "Eins" & "Zwei". Wenn der Benutzer "Eins" auswählt, wird das clientseitige Skript ausgeführt. Wenn der Benutzer "Zwei" auswählt, wird das serverseitige Skript ausgeführt.

Problem: Das Client-Skript initiiert das Postback durch Aufruf von __doPostBack. Es tritt jedoch kein Post-Back auf, wenn auf der Seite auch kein LinkButton-, Calendar- oder WizardStep-Steuerelement vorhanden ist. Ich habe tatsächlich alle Standard-Tools in der Visual Studio Toolbox durchlaufen und alle getestet. Es muss einer von diesen drei sein.

Umgehen: Fügen Sie einen Link-Button hinzu, der von einem Bereich umgeben ist, dessen Anzeige auf "Keine" gesetzt ist.

<span style="display:none;"> 
    <asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton> 
</span> 

Frage: Kann jemand eine Erklärung für dieses Verhalten liefern oder eine bessere fix als meine bieten „Work Around“?

Quelle - Javascript (ich es zwischen dem Kopf Tags platziert)

<script language="javascript" type="text/javascript"> 
    function DropDownList1_change(elementRef) { 
     var selectedIndex = elementRef.selectedIndex; 
     if (selectedIndex > 0) { 
      var selectedValue = elementRef.options[selectedIndex].value; 
      if (selectedValue == "One") { 
       alert("Because you selected 'One', special javascript code will be executed"); 
       // Special javascript code goes here 
       return; 
      } 
      else if (selectedValue == "Two") { 
       // Special server code gets executed on server DropDownList1_SelectedIndexChanged 
       __doPostBack('DropDownList1', ''); 
      } 
     } 
    } 
</script> 

Quelle - ASPX Steuert

<asp:DropDownList ID="DropDownList1" runat="server" onchange="DropDownList1_change(this)" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"> 
     <asp:ListItem>-Select-</asp:ListItem> 
     <asp:ListItem>One</asp:ListItem> 
     <asp:ListItem>Two</asp:ListItem> 
    </asp:DropDownList> 
    <br /> 

    <!-- For some unknown reason __doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page -->  
    <span style="display:none;"> 
     <asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton> 
    </span> 

    Time of last Post Back: <asp:Label ID="Label1" runat="server"></asp:Label><br /> 
    Time of OnSelectedIndexChanged: <asp:Label ID="Label2" runat="server"></asp:Label> 

Quelle - Code hinter

protected void Page_Load(object sender, EventArgs e) 
    { 
     Label1.Text = DateTime.Now.ToLongTimeString(); 
    } 

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     Label2.Text = DateTime.Now.ToLongTimeString(); 
    } 

Zusätzliche Ressource - Ich fand den folgenden Artikel nach dem Posten dieser Frage. Es ist ein sehr alter Microsoft Artikel und der einzige Microsoft Artikel, den ich gefunden habe, der die spezifische Beschränkung von DropDowns erwähnt, gibt & Postbacks zurück. Ich habe nicht tief in ihre Lösung gegraben und bin mir nicht sicher, ob die Zeit es mir erlauben wird. Hauptsächlich posten Sie es für den Fall, dass meine Lösung fehlschlägt oder nicht für jemand anderen funktioniert.

Intuitiv können Sie ein Bestätigungsdialogfeld für eine Dropdown denken Zugabe ist identisch mit Zugabe eines solchen Dialogfeld für ein Button Web Kontrolle. Das heißt, setzen Sie einfach das clientseitige Attribut der DropDownList auf etwas wie: return confirm (...) ;. Verwenden: DropDownListID.Attributes ("onchange") = "return confirm (...);" Leider funktioniert dies nicht wie gewünscht, da ein AutoPostBack DropDownList Onchange-Attribut auf ein Bit JavaScript gesetzt wird, die ein Postback verursacht, nämlich einen Aufruf an die clientseitige __doPostBack Funktion.Wenn das onchange Attribut Einstellung sich programmatisch, ist das Endergebnis, dass die gerenderte clientseitige Onchange Ereignishandler sowohl Ihren Code und den Anruf zu __doPostBack hat:

Der Artikel ist für „Bestätigung lange so Suche mit Autopostback Dropdownlists“

https://msdn.microsoft.com/en-us/library/aa479302.aspx

+0

Ehrlich gesagt, ist die beste Problemumgehung, die ich habe, WebForms nicht zu verwenden. Die Technologie ist absolut schrecklich, um im Browser irgendetwas Brauchbares zu tun, wie das, was Sie tun. Wenn Sie WebForms verwenden, dann sollten Sie meiner Meinung nach 100% tun, was bedeuten würde, anstatt "onchange" zu verwenden und herkömmliches Javascript auszuführen, Ihr 'One' -Szenario innerhalb des Postbacks selbst zu behandeln und möglicherweise angepasstes Javascript auf die Antwort davon zu registrieren Postback. –

+0

Beobachten Sie dieses Verhalten in einem neuen Projekt? Ich habe versucht, das Problem (mit VS 2010 und .NET Framework 4.0) zu reproduzieren und das Postback wird jedes Mal durch Auswahl eines Elements in der DropDownList durchgeführt. – ConnorsFan

+0

Ich bekomme das gleiche Verhalten in einem neuen Projekt; Ich habe sowohl eine leere neue Website als auch ein Webanwendungsprojekt zum Testen erstellt. Ich benutze VS 2010, .NET Framework 4, Windows 7 32 Bit & Cassini (werde es von IIS versuchen). – Dave

Antwort

3

Es wurden 2 Lösungen.

Lösung 1: Eine bessere work around als eine Link-Schaltfläche Hinzufügen von versteckten span-Tags umgeben ist die folgende auf die Seite zu laden Ereignis hinzuzufügen. Dies stellt sicher, dass die Funktion __doPostBack verfügbar ist.

protected void Page_Load(object sender, EventArgs e) 
{ 
    Page.ClientScript.GetPostBackEventReference(this, string.Empty); 
} 

Die Funktion __doPostBack nur dann erzeugt wird, wenn eine Steuerung in Form Postbacks durchzuführen es braucht. Dazu gehören Steuerelemente wie der LinkButton und andere Steuerelemente, für die AutoPostBack auf true festgelegt ist. Tatsächlich können nur die Button- und ImageButton-Steuerelemente Postbacks ohne __doPostBack ausführen (siehe this article). Zum Beispiel können wir in der HTML-Ausgabe sehen, dass ein Linkbutton auf diese Weise wiedergegeben wird:

<a id="lnk" href="javascript:__doPostBack(&#39;lnk&#39;,&#39;&#39;)">My link</a> 


Lösung 2: Der folgende Ansatz erreicht die gleiche Sache ohne __doPostBack zu verwenden.

Im vorliegenden Fall, Sie AutoPostBack="true" für das Dropdownlist setzen könnte:

<asp:DropDownList AutoPostBack="true" onchange="if (!confirmPostBack(this)) return false;" ... > 

Die onchange Ereignishandler false zurückkehren würde, wenn Sie die Postbacks verhindern wollen. Die Javascript-Funktion könnte so etwas wie dieses:

function confirmPostBack(ddl) 
{ 
    if (condition) { 
     ... 
     return true; 
    } 
    else { 
     ... 
     return false; 
    } 
} 

Wichtige: Die onchange Event-Handler sollte nichts zurückgeben der Postbacks stattfinden zu lassen. Sie können diese Syntax verwenden:

onchange="if (!confirmPostBack(this)) return false;" 

Aus Gründen wahrscheinlich in der in der Anfrage genannten Artikel erläutert, ist die folgende Syntax funktioniert nicht. Die Rückkehr true verhindert immer noch das Postback.

onchange="return confirmPostBack(this);" // Does not work! 
+0

So habe ich es zuerst versucht. Die Rückgabe von true/false funktioniert jedoch nicht mit Javascript, das durch ein Dropdown-Menü ausgelöst wird. Nach einem Button-Klick kann ein Postback mit einer Rückgabe false abgebrochen werden, jedoch nicht mit einem Dropdown. Dies ist eine wenig bekannte Einschränkung bei Dropdowns. Es gibt einige Arbeitsumgebungen im Internet. Bitte nicht die Mühe machen, irgendeinen Grund zu veröffentlichen, den ich schon alle ausprobiert habe. Ich möchte nur verstehen, warum ich einen LinkButton hinzufügen muss, damit __doPostBack funktioniert. – Dave

+0

Sie sagen, dass es nicht funktioniert. Aber es funktioniert. Getestet 100%. Die wichtige Sache ist, wenn das Postback auftreten soll, gib nichts zurück, nicht einmal "wahr". – ConnorsFan

+0

Ich verstehe nicht, was Sie meinen, indem Sie nichts zurückgeben. Die confirmPostBack-Funktion, die Sie geschrieben haben, gibt entweder wahr oder falsch zurück. – Dave