4. Triggers
So far, the examples you've
seen have used the built-in behavior of the UpdatePanel. In the next
example, you'll use the UpdatePanel in a slightly more sophisticated
page, and you'll learn to control its refreshes with triggers.
This page lets the user specify several
details—such as text, font, colors, border options, and so on—and then
updates a portion of the page to show the greeting card.
The first version
allowed the user to specify a number of options at once, and then click
a button to update the greeting card. The second version used automatic
postback events, so that the greeting card was updated after every
change. This second approach gave a more immediate result, but the cost
was a less responsive user interface with distracting flicker. If this
version of the greeting card maker was running on a slow web server (or
over a slow network), the problems get even worse. That's because after
every postback the user is forced to wait for the page update before
making another change.
The UpdatePanel gives you the
ability to get the best of both versions. You can create a greeting card
page that updates its display automatically but feels more responsive
and doesn't lock the user out.
The simplest approach is to add a
ScriptManager and wrap the entire web page—including the controls and
the greeting card—in one giant UpdatePanel. Here's the markup you'd use:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<!-- These are the controls for creating the greeting card. -->
<div style="...">
Choose a background color:<br />
<asp:DropDownList ID="lstBackColor" runat="server"
Width="194px" AutoPostBack="True">
</asp:DropDownList>
<br /><br />
Choose a foreground (text) color:<br />
<asp:DropDownList ID="lstForeColor" runat="server"
Height="22px" Width="194px" AutoPostBack="True" >
</asp:DropDownList>
<br /><br />
Choose a font name:<br />
<asp:DropDownList ID="lstFontName" runat="server"
Height="22px" Width="194px" AutoPostBack="True">
</asp:DropDownList>
<br /><br />
Specify a font size:<br />
<asp:TextBox ID="txtFontSize" runat="server"
AutoPostBack="True">
</asp:TextBox>
<br /><br />
Choose a border style:<br />
<asp:RadioButtonList ID="lstBorder" runat="server"
Height="59px" Width="177px" Font-Size="X-Small"
AutoPostBack="True" RepeatColumns="2">
</asp:RadioButtonList>
<br /><br />
<asp:CheckBox ID="chkPicture" runat="server"
Text="Add the Default Picture" AutoPostBack="True">
</asp:CheckBox>
<br /><br />
Enter the greeting text below:<br />
<asp:TextBox ID="txtGreeting" runat="server"
Height="85px" Width="240px" TextMode="MultiLine"
AutoPostBack="True">
</asp:TextBox>
</div>
<!-- This is the panel that shows the greeting card. -->
<asp:Panel ID="pnlCard" runat="server" ... >
<asp:Label ID="lblGreeting" runat="server" Width="272px"
Height="150px"></asp:Label>
<br />
<asp:Image ID="imgDefault" runat="server" Width="212px" Height="160px"
Visible="False"></asp:Image>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
The greeting card is then generated when the Page.Load event fires:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) _
Handles Me.Load
If Not Me.IsPostBack Then
' (Initialize all the controls here.)
Else
' Refresh the greeting card.
UpdateCard()
End If
End Sub
The UpdatePanel watches its
child controls and intercepts any events that could trigger a postback.
The Button.Click is an obvious example, but in this example the
TextBox.TextChanged and ListBox.SelectedItemChanged events also trigger a
postback, because these controls set the AutoPostBack property to True.
Thus, these events are also intercepted by the UpdatePanel. If these
controls didn't use the AutoPostBack property, they wouldn't trigger a
postback, the UpdatePanel wouldn't get involved, and the greeting card
won't be updated until another control causes a postback.
This solution achieves the desired result. Although the greeting card page looks essentially the same (see Figure 4),
when you interact with the controls on the left, the card on the right
is updated without a postback. If you make several changes in quick
succession, you'll trigger several postbacks, and the result from the
last postback (with the completely updated card) will be used.
Although this example works
perfectly well, it's doing more work than necessary. Because the entire
page is wrapped in the UpdatePanel, the HTML for the entire page is
refreshed. A better option is to wrap just the label and image that
represents the greeting card in the UpdatePanel. Unfortunately, this
won't work. Once you move the other controls out of the UpdatePanel,
their events won't be intercepted any longer, and they'll trigger
full-page postbacks with the familiar flicker.
The solution is to
explicitly tell the UpdatePanel to monitor those controls, even though
they aren't inside the UpdatePanel. You can do this by adding triggers
to the UpdatePanel. You add one trigger for each button.
Here's the markup you need:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<!-- The controls for creating the greeting card go here. -->
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<!-- This is the panel that shows the greeting card. -->
<asp:Panel ID="pnlCard" runat="server" ... >
<asp:Label ID="lblGreeting" runat="server" Width="272px"
Height="150px"></asp:Label>
<asp:Image ID="imgDefault" runat="server" Width="212px" Height="160px"
Visible="False"></asp:Image>
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="lstBackColor" />
<asp:AsyncPostBackTrigger ControlID="lstForeColor" />
<asp:AsyncPostBackTrigger ControlID="lstFontName" />
<asp:AsyncPostBackTrigger ControlID="txtFontSize" />
<asp:AsyncPostBackTrigger ControlID="lstBorder" />
<asp:AsyncPostBackTrigger ControlID="chkPicture" />
<asp:AsyncPostBackTrigger ControlID="txtGreeting" />
</Triggers>
</asp:UpdatePanel>
You don't need to type your
triggers in by hand. Instead, you can use the Visual Studio Properties
window. Just select the UpdatePanel, click the Triggers property in the
Properties window, and click the ellipsis (...) that appears in the
Triggers box. Visual Studio will open a dialog box where you can add as
many triggers as you want, and pick the control for each trigger from a
drop-down list.
|
|
These triggers tell the
UpdatePanel to intercept the default event in these seven controls.
(You could specify the event you want to monitor by setting the
EventName property of the trigger, but you don't need to, because you're
using the most commonly used default event for each one.) As a result,
the page works the same as it did before—it just refreshes a smaller
portion of the page after each asynchronous request.
Technically, the UpdatePanel
always uses triggers. All the controls inside an UpdatePanel
automatically become the triggers for the UpdatePanel. However, you need
to add the triggers if the controls are placed elsewhere in the page.
NOTE
You can add the same
trigger to several different conditional UpdatePanel controls, in which
case that event will update them all.
You can use triggers in one
other way. Instead of using them to monitor more controls, you can use
them to tell the UpdatePanel to ignore certain controls. For example,
imagine you have a button in your UpdatePanel. Ordinarily, clicking that
button will trigger an asynchronous request and partial update. If you
want it to trigger a full-page postback instead, you simply need to add a
PostBackTrigger (instead of an AsynchronousPostBackTrigger).
For example, here's an
UpdatePanel that contains a nested button that triggers a full postback
rather than an asynchronous postback:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Font-Bold="True"></asp:Label>
<br />
<br />
<asp:Button ID="cmdPostback" runat="server" Text="Refresh Full Page" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="cmdPostback" />
</Triggers>
</asp:UpdatePanel>
This technique isn't as common,
but it can be useful if you have several controls in an UpdatePanel that
perform limited updates (and so use asynchronous request) and one that
performs more significant changes to the whole page (and so uses a
full-page postback).