To read the article online, visit http://www.4GuysFromRolla.com/articles/061808-1.aspx

Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Using the Timer Control

By Scott Mitchell


Introduction


Microsoft's ASP.NET AJAX framework ships with a mere five Web controls: the ScriptManager and ScriptManagerProxy; the UpdatePanel; the UpdateProgress; and the Timer. Previous installments in this article series have examined all but one control, the Timer. As we've seen from the first installment, all web pages that use the framework must have precisely one ScriptManager control on the page. The UpdatePanel control defines a region on the screen whose content is updated via partial page postbacks, and the UpdateProgress control provides visual feedback during the execution of a partial page postback. The Timer control, which is the focus of this installment, raises a postback every time a specified number of milliseconds has elapsed.

The Timer control is useful in scenarios where a portion of the screen needs to be updated every so often. For example, many financial websites display stock quotes that are refreshed periodically. Prior to AJAX, refreshing the stock quote entailed reloading the entire document, which would result in a screen flash and necessitate the browser re-downloading the entire content of the page (even though the only change that has occurred is the stock quote). Using AJAX techniques we can have the page asynchronously communicate with the server to get the latest quote every n millisconds and seamlessly update the quote on screen. The Timer control, along with the UpdatePanel, make implementing such scenarios a breeze.

This article shows how to use the Timer control to trigger a partial page postback every five seconds. It also shows how to start and stop the Timer through both server-side and client-side code. Read on to learn more!

Performing a Postback Every N Milliseconds


The Timer control is designed to periodically cause a postback. Its Interval property specifies the number of milliseconds to elapse before the postback is triggered. On postback, the Timer's Tick event is raised.

That's all there is to it! Realize that the Timer control causes a full page postback by default, but chances are you want the Timer to raise a partial page postback. This can be accomplished in one of two ways:

  • By placing the Timer control with an UpdatePanel. When the Timer "ticks" it raises a postback, but because it's in an UpdatePanel it becomes a partial page postback.
  • Placing the Timer control outside the UpdatePanel, but adding it as an UpdatePanel trigger. See the Using the UpdatePanel installment for a discussion on how to trigger a partial page postback from an UpdatePanel using controls outside of the UpdatePanel.
To update the display or perform some other logic when the Timer postsback, create an event handler for its Tick event.

The download available at the end of this article includes a demo named Timer.aspx that shows how to use a Timer to asynchronously update the contents of an UpdatePanel every five seconds. Specifically, this demo displays the real-time stock price of a fictional company. To create this demo yourself, start by creating a new page; configure it to use the ASP.NET AJAX framework by adding a ScriptManager to the page. Also add a Label control to the page named CurrentTime, which we'll use to display the time the page was last updated via a full page postback. Next, add an UpdatePanel control and put the contents that are to be updated every five seconds within it. I have added three display-related Web controls in the UpdatePanel:

  • A Label control named StockPrice, which is used to display the company's stock price.
  • An Image control, which displays either a picture of a bag of money or a broke guy, depending on the current stock price. (My lame attempt at humor.)
  • Another Label control (named CurrentPanelTime) which displays the time the UpdatePanel was last updated.
I also added a Timer control to the UpdatePanel and set its Interval property to 5000. Every five seconds the Timer will "tick," causing a partial page postback and raising its Tick event.

At this point your page's declarative markup should look similar to the following:

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

This page last experienced a "full" postback at:
<asp:Label ID="CurrentTime" runat="server"></asp:Label></p>

<asp:UpdatePanel ID="MyUpdatePanel" runat="server">
   <ContentTemplate>
      Current stock price:
      <asp:Label ID="StockPrice" runat="server" Font-Bold="True"></asp:Label><br />
      <asp:Image ID="ResultsImage" runat="server" Width="100px" /><br />
      <br />
      
      The UpdatePanel was last refreshed at:
      <asp:Label ID="CurrentPanelTime" runat="server"></asp:Label>
      <br />
      
      <asp:Timer ID="MyTimer" runat="server" Interval="5000">
      </asp:Timer>

   </ContentTemplate>
</asp:UpdatePanel>

Add a method named UpdateStockPrice to the page's code-behind class. This method needs to determine the current stock quote, display it in the StockPrice Label, and load the appropriate image. As the following code shows, the current stock quote is simply a randomly chosen number between 0 and 100. Furthermore, the StockPrice Label's ForeColor property is set to Red and the broke image is displayed if the stock price is less than $50.00; the ForeColor property is set to Green and the money bags image is displayed when the stock price is $50.00 or greater.

private void UpdateStockPrice()
{
   // Determine the new (random) stock price
   Random rnd = new Random();
   decimal quote = Convert.ToDecimal(rnd.NextDouble()) * 100.0M;
   StockPrice.Text = quote.ToString("c");

   if (quote < 50.0M)
   {
      StockPrice.ForeColor = System.Drawing.Color.Red;
      ResultsImage.ImageUrl = "~/Images/Broke.gif";
   }
   else
   {
      StockPrice.ForeColor = System.Drawing.Color.Green;
      ResultsImage.ImageUrl = "~/Images/MoneyBags.jpg";
   }
}

The UpdateStockPrice method needs to be called when the page is first loaded as well as whenever the Timer control's Tick event is raised. Create a Page_Load event handler in the code-behind class and set the two Labels' Text properties to the current time. Also call the UpdateStockPrice method if Page.IsPostback is False (i.e., the page is being visited for the first time and not on a postback):

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

   // Update the stock price on the first page visit (not on subsequent postbacks)
   if (!Page.IsPostBack)
      UpdateStockPrice();
}

Next, create an event handler for the Timer's Tick event and, from there, call the UpdateStockPrice method:

protected void MyTimer_Tick(object sender, EventArgs e)
{
   // Update the stock price
   UpdateStockPrice();
}

With the declarative markup and code in place, visit the page through a browser. Every five seconds the Timer causes a partial page postback, the current stock price is computed, and the display is updated. The following screen shot shows the page when it first visited. Note that the time the page last experienced a "full" postback (the initial page load) and the time the UpdatePanel was last updated are the same.

The page, when first visited through a browser.

And here is the page five seconds later, after the stock price has been updated. Note that the time shown in the UpdatePanel is five seconds ahead of the time the page was last loaded.

The page, after the Timer triggered a partial page postback.

Starting and Stopping the Timer Control


By default, the Timer control starts its countdown as soon as the page is loaded, and continues to trigger postbacks every n milliseconds. If you need to stop the Timer from ticking, you have two options:
  • Disable the Timer on the server-side, or
  • Stop the Timer on the client-side.
The Timer control has an an Enabled property that specifies whether the Time is active or not. This is a server-side property, meaning that if you want to change this value you need to perform a postback of some kind (either a full page postback or a partial page postback). Using the client-side option we can use JavaScript to stop (or start) the Timer, which saves a postback. The client-side option, however, requires a bit more JavaScript code and work than the server-side option. The download at the end of this article includes a server-side demo (TimerPause.aspx) and a client-side demo (TimerPauseClient.aspx). Let's look at both approaches.

To implement the server-side functionality, I augmented the Timer control example we looked at previously to include a Button Web control in the UpdatePanel. I set the Button's Text property to "Pause" and created a Click event handler. In the event handler I toggle the Timer control's Enabled property value and update the Button's Text property from "Pause" to "Resume" when stopping the Timer, and from "Resume" back to "Pause" when restarting it. I also call the UpdateStockPrice method when resuming the Timer so that resuming it immediately updates the stock price (rather than waiting another five seconds for the Timer to "tick").

protected void ToggleServerSide_Click(object sender, EventArgs e)
{
   if (MyTimer.Enabled)
   {
      MyTimer.Enabled = false;
      ToggleServerSide.Text = "Resume";
   }
   else
   {
      MyTimer.Enabled = true;
      ToggleServerSide.Text = "Pause";

      // Refresh the stock price
      UpdateStockPrice();
   }
}

To start or stop the Timer control from the client-side you need to get a reference to the Timer control and then call its _startTimer or _stopTimer functions, respectively. The download at the conclusion of this article includes a handy JavaScript function named ToggleTimer, which, as its name implies, toggles the status of a Timer control using client-side techniques. This method expects two input parameters: a reference to a button (the "Pause"/"Resume" button) and the id value of the Timer control. It gets a reference to the Timer control via the ASP.NET AJAX framework Client Library $get(id) function and then, depending on whether the Timer is active or not, stops or starts it. The button's value attribute, which corresponds to the text displayed by the Button, is also updated. Here's the JavaScript function in its entirety.

var timerEnabled = true;
function ToggleTimer(btn, timerID)
{
   // Toggle the timer enabled state
   timerEnabled = !timerEnabled;

   // Get a reference to the Timer
   var timer = $find(timerID);

   if (timerEnabled)
   {
      // Start timer
      timer._startTimer();
      
      // Immediately raise a tick
      timer._raiseTick();

      btn.value = 'Pause';
   }
   else
   {
      // Stop timer
      timer._stopTimer();

      btn.value = 'Resume';
   }
}

This function is located in the TimerLogic.js file in the ~/Scripts folder. To include it in a particular ASP.NET Web page, add it to the ScriptManager's Scripts collection. To use this JavaScript function, add the HTML for a button to the UpdatePanel an in its client-side onclick event handler call the ToggleTimer function, passing in a reference to the button (this) and the fully qualified client-side id value of the Timer control. (Note that the client-side id is accessible via the Timer control's ClientID property.)

<asp:ScriptManager ID="MyManager" runat="server">
   <Scripts>
      <asp:ScriptReference Path="~/Scripts/TimerLogic.js" />
   </Scripts>
</asp:ScriptManager>

<asp:UpdatePanel ID="MyUpdatePanel" runat="server" UpdateMode="Conditional">
   <ContentTemplate>
      Current stock price: ...

      

<input type="button" id="btnToggleTimer" value="Pause" onclick="ToggleTimer(this, '<%=MyTimer.ClientID%>');" />



      ...
   </ContentTemplate>
</asp:UpdatePanel>

The following screen shot shows the page with the Pause/Resume button in action. When the page is first visited the Timer is active; consequently, the Button is labeled "Pause".

The page includes a Pause button to stop the Timer.

Clicking the Pause button stops the Timer control and updates the button's text to "Resume". The Timer won't "tick" again until the Resume button is clicked.

The Timer has been paused. It won't tick again until the Resume button is clicked.

Conclusion


The ASP.NET AJAX framework Timer control makes it easy to trigger a postback (or, more likely, a partial page postback) every n milliseconds. Set the Timer's Interval property to the appropriate number of milliseconds and then create an event handler for the control's Tick event. That's all there is to it! And with a little client- and/or server-side programming you can add functionality to stop and restart the Timer.

Happy Programming!

  • By Scott Mitchell


    Attachments:


  • Download the Demo Code Used in this Article

  • Article Information
    Article Title: ASP.NET.Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Using the Timer Control
    Article Author: Scott Mitchell
    Published Date: June 18, 2008
    Article URL: http://www.4GuysFromRolla.com/articles/061808-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers