ASP.NET AJAX History Control

Ein häufiges Ärgernis von AJAX Anwendungen tritt dann zu Tage, wenn die Vor- und Zurück-Buttons des Browsers verwendet werden. Eine per AJAX ausgeführte Aktion wird vom Browser nicht als Seitenwechsel interpretiert und taucht somit auch nicht im Seitenverlauf auf. Im schlimmsten Fall landet der Benutzer der Seite also wieder am Beginn und hat alle getätigten Änderungen und Eingaben sind verloren.

Mit dem Service Pack 1 des .NET Framework 3.5 wurde der AJAX ScriptManager um eine neue Funktionalität erweitert. Diese neue Funktion setzt nach jedem AJAX Aufruf einen Verlaufspunkt im Browser, so dass die Vor- und Zurück-Buttons wieder verwendet werden können.  Das folgende Beispiel zeigt die Verwendung anhand einer DropDownListe und eines UpdatePanels auf. Nach dem Auswählen eines Eintrags wird der Bereich im UpdatePanel aktualisiert und die Auswahl in einem Label ausgegeben.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<asp:UpdatePanel ID="updatePnl" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlAuswahl" runat="server" OnSelectedIndexChanged="ddlAuswahl_SelectedIndexChanged" AutoPostBack="true">
            <asp:ListItem>Eintrag 1</asp:ListItem>
            <asp:ListItem>Eintrag 2</asp:ListItem>
            <asp:ListItem>Eintrag 3</asp:ListItem>
            <asp:ListItem>Eintrag 4</asp:ListItem>
            <asp:ListItem>Eintrag 5</asp:ListItem>
        </asp:DropDownList>
        <br />
        Auswahl: <asp:Label ID="lblAuswahl" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void ddlAuswahl_SelectedIndexChanged(object sender, EventArgs e)
    {
        lblAuswahl.Text = ddlAuswahl.Text;
    }
}


Ohne die AJAX Funktionalität, die das UpdatePanel bereitstellt, wird nach jeder Auswahl die Seite neu geladen und somit auch der Zurück-Button im Browser aktiv. Sobald jedoch das UpdatePanel verwendet wird, bleibt der Button ausgegraut.

 HistoryIE0 

Neben dem setzen der Eigenschaft EnableHistory des ScriptManagers auf true, ist es weiterhin nötig einen HistoryPoint zu setzen. Dies wird im EventHandler der DropDownListe erledigt.

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
    ScriptManager1.AddHistoryPoint("index", ddl.SelectedIndex.ToString(), "Point " + ddl.SelectedValue);
}

Um die gesetzten Werte später wieder abzurufen und - in diesem Beispiel - den richtigen Index der DropDownListe zu setzen, ist es nötig den Event OnNavigate des ScriptManagers zu abonnieren. An den EventHandler wird der Wert übergeben, welcher vorher mit Hilfe der Methode AddHistoryPoint gesetzt wurde.

protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
    string selectedIndex = e.State["index"];

    if (String.IsNullOrEmpty(selectedIndex))
        ddl.SelectedIndex = 0;
    else
        ddl.SelectedIndex = Convert.ToInt32(selectedIndex);
}

Nach dem Starten der Anwendung ist das Ergebnis ein aktiviertes Zurück-Button im Browser.

HistoryIE1

Durch die flexible Struktur und die Events ist es möglich das Verhalten in komplexen AJAX-Anwendungen an die eigenen Bedürfnisse anzupassen.

Noch ein Hinweis:

Wird die Eigenschaft EnableHistory auf false gesetzt, ohne den Aufruf der Methode AddHistoryPoint() zu entfernen, wird der Aufruf mit einer Exception quittiert. Um dies zu verhindern kann die Eigenschaft zusätzlich noch im EventHandler abgefragt werden. Weiterhin gibt die Eigenschaft IsNavigating Auskunft darüber, ob momentan mit Hilfe des HistoryControls navigiert wird.

protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
    if (ScriptManager1.EnableHistory && ScriptManager1.IsNavigating == false)
    {
        ScriptManager1.AddHistoryPoint("index", ddl.SelectedIndex.ToString(), "Point " + ddl.SelectedValue);
    }
}

Das Beispielprojekt kann hier herruntergeladen werden.

  1. No Comments