Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

A Stoppable Timer Control for ASP.NET Atlas

4.89/5 (19 votes)
30 Jul 2006CPOL2 min read 1   632  
This article presents a timer control that resolves an issue with the Atlas Timer server control. The issue being the Atlas TimerControl cannot be stopped from the server side code.

Introduction

ASP.NET Atlas has a timer server control which periodically postbacks to the server. However, the TimerControl has a bug that prevents it to be stopped from server side code during partial rendering. Time and again, I encounter the question in Atlas forums which ask for a workaround to this bug. This article is based on my post in Atlas forums, and has detailed explanation on how to solve this problem. Hopefully, the issue will be resolved in a future version of Atlas.

Using the Code

Here are the steps you must take to use this control:

  1. Copy the StoppableTimer.cs file to the App_Code directory of your web site.
  2. Modify the web.config file to add the following element:
    XML
    <configuration>
       <system.web>
           <pages>
            <tagMapping>
                <add tagType="Microsoft.Web.UI.Controls.TimerControl" 
                     mappedTagType="VRK.Controls.StoppableTimer,App_Code"/>
            </tagMapping>
  3. The configuration setting automatically allows your class to be used instead of the Atlas TimerControl without any changes to existing web pages. In a new page, you can continue to use the control using the following syntax:
    HTML
    <atlas:TimerControl ID="Timer1" 
          runat="server" Interval="500" OnTick="Timer1_Tick" 
          Enabled="false" />
  4. If the bug is fixed in a future CTP, you can just remove the configuration setting, and everything will work as it is.

How it Works

There are two problems with the Atlas server control which causes this bug:

  1. The control does not generate any ID for the timer.

  2. It does not try to stop the timer in response to postbacks or callbacks.

The timer control presented in the article modifies the rendering of the TimerControl as follows:

C#
protected override void RenderScript(ScriptTextWriter writer)
{
  if (!IsPageInPartialRendering)
  {
    writer.WriteStartElement("timer");
    writer.WriteAttributeString("id", this.UniqueID);
    writer.WriteAttributeString("interval", 
           this.Interval.ToString(CultureInfo.InvariantCulture));
    writer.WriteAttributeString("enabled", this.Enabled.ToString().ToLower());
    writer.WriteStartElement("tick");
    writer.WriteStartElement("postBack");
    writer.WriteAttributeString("target", this.UniqueID);
    writer.WriteAttributeString("eventArgument", string.Empty);
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndElement();
  }
}

As you can see, the control renders the XML-Script except for partial rendering. During partial rendering, the timer object on the client web page is not destroyed, so all that needs to be done is to enable or disable the client-side object. This is done in the OnPreRender method:

C#
protected override void OnPreRender(EventArgs e)
{
   if (IsPageInPartialRendering)
   {
     string scriptSnippetFormat = "$object(\"{0}\").set_enabled({1});";
     string scriptSnippet = 
       String.Format(scriptSnippetFormat, 
       this.UniqueID, 
       this.Enabled.ToString().ToLower());

     Page.ClientScript.RegisterStartupScript(
        GetType(),
        this.UniqueID,
        scriptSnippet,
        true);
    }

    base.OnPreRender(e);
}

The only remaining interesting part of the code is obtaining the instance of the script manager on the page and finding whether the ScriptManager is in partial rendering mode:

C#
bool IsPageInPartialRendering
{
   get
   {
      ScriptManager manager = ScriptManager.GetCurrent(this.Page);
      return (manager != null && manager.IsInPartialRenderingMode);
   }
}

Conclusion

This is a quick fix for a bug that exist in Atlas as I know in June CTP. It may be fixed in the coming releases of Atlas. Fortunately, if you use the fix as described, all you will need to do is to change the configuration setting, and you don't need to change any of the source code of any page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)