TOC

The community is working on translating this tutorial into Portuguese, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".

Controls:

UpdatePanel history

A big problem with AJAX enabled pages in general, is that, by design, each action doesn't represent a state in your browser, which means that you can't use the Back and Forward buttons to shift between states, and because the URL doesn't change, a specific state can't be bookmarked or linked to by the user. This effectively limits the situations in where you can use AJAX in general and the UpdatePanel control specifically. Fortunately, Microsoft has solved this problem with the History feature. It can be enabled on the ScriptManager control, and basically works by adding information to the URL after the # character, which is normally mostly used for navigating between various parts of the same page. Let's try creating a sample page which will show you the problem, and then we fix it afterwards:

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

<asp:UpdatePanel runat="server" ID="pnlColorSelect">
<ContentTemplate>
    <asp:DropDownList runat="server" ID="ddlColor" AutoPostBack="true" OnSelectedIndexChanged="ddlColor_SelectedIndexChanged">
        <asp:ListItem Value="Red">Red</asp:ListItem>
        <asp:ListItem Value="Blue">Blue</asp:ListItem>
        <asp:ListItem Value="Green">Green</asp:ListItem>
    </asp:DropDownList>
    <br /><br />
    Selected color: <asp:Label runat="server" ID="lblSelectedColor" />
</ContentTemplate>
</asp:UpdatePanel>    

We also need a CodeBehind method to handle the selection of a new color:

protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
{
    lblSelectedColor.Text = ddlColor.SelectedValue;
    lblSelectedColor.BackColor = System.Drawing.Color.FromName(ddlColor.SelectedValue);
}

It's really quite simple, so try running the page and see for your self. When you select a new color from the dropdown list, the change is reflected in the label control below it, and because of the UpdatePanel around it, no real postback is performed and the label is updated without the page reloading. This is all very good, but as you can see, no matter how many times you change the color, the URL does not change and no state is tracked, resulting in dead Back and Forward buttons. Let's change that, by making the following changes: The ScriptManager should have the EnableHistory property set to True and we need to subscribe to the OnNavigate event, like this:

<asp:ScriptManager runat="server" ID="MainScriptManager" EnableHistory="true" OnNavigate="MainScriptManager_Navigate" />

In the CodeBehind, we add a single line to our dropdown list event, and then we define our Navigate event for the ScriptManager, like this:

protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
{
    lblSelectedColor.Text = ddlColor.SelectedValue;
    lblSelectedColor.BackColor = System.Drawing.Color.FromName(ddlColor.SelectedValue);
    MainScriptManager.AddHistoryPoint("SelectedColor", ddlColor.SelectedValue);
}

protected void MainScriptManager_Navigate(object sender, HistoryEventArgs e)
{
    string color = e.State["SelectedColor"];
    if (!String.IsNullOrEmpty(color))
    {
        lblSelectedColor.Text = color;
        lblSelectedColor.BackColor = System.Drawing.Color.FromName(color);
    }
}

Try running the page now. Each time you change the color, you will see the URL change, but still without a real postback/page reload, and you can now use your Back/Forward buttons in the brower. You will also see that the URL in the address bar actually be copied to a new browser window, and when the page is loaded, the color is now the same as when you copied the URL. It works! One thing that might bother you, is the fact that the URL looks very cryptic, like this:

Default.aspx#&&/wEXAQUNU2VsZWN0ZWRDb2xvcgUFR3JlZW6BwCysI0shYsZauxImdaPIIPEYSA==

That's because the values are encoded for security reasons. However, in a lot of cases, the values you store are really not that important and you might want a more naturally looking URL instead of the more secure one. This can be accomplished by using the EnableSecureHistoryState property on the ScriptManager, like this:

<asp:ScriptManager runat="server" ID="MainScriptManager" EnableHistory="true" OnNavigate="MainScriptManager_Navigate" EnableSecureHistoryState="false" />

Now when you use the page, the URL will look like this instead:

Default.aspx#&&SelectedColor=Red

Much simpler, but obviously it also allows the user to enter values that you may not have expected, which you should consider and prepare for when using this feature.