Disable a timer at every level of your ASP.NET control hierarchy

Audience

Everyone

Even though this sounds like a really simple thing, what if you do not know the name of the controls, and you do not want to have to add a bit of code that you, or another may developer may forget to every piece of code with a timer in it. The problem I have is that if you have a DropDownList on the same page as a update panel that updates based on a timer, you get a little interference.

If the user has the DropDownList open when the update occurs then the DropDownList closes. Very annoying.

The standard FindControl does not work as it requires an ID, so what if all you have is a type?

Well, you need a little extension method 🙂

Imports System.Runtime.CompilerServices
Imports System.Web
Imports System.Web.UI

Module WebExtensions

    <Extension()> _
    Friend Sub FindControls(Of T)(ByVal control As Control, ByVal list As List(Of T))
        If control.HasControls Then
            Dim timers = control.Controls.OfType(Of T)()
            list.AddRange(timers)
            Dim subcontrols = From c In control.Controls Where Not timers.Cast(Of Control).Contains(c)
            For Each c In subcontrols.Cast(Of Control)()
                c.FindControls(Of T)(list)
            Next
        End If
    End Sub

    <Extension()> _
    Friend Function FindControls(Of T)(ByVal control As Control) As List(Of T)
        Dim l As New List(Of T)
        control.FindControls(Of T)(l)
        Return l
    End Function

End Module

I am pretty sure this is not the most efficient of code, and any recommendation on improving it are welcome…

Once this is in place it is easily called and actioned upon:

Sub OnPagePreRender(ByVal sender As Object, ByVal e As EventArgs)

    ' Fix for pages with drop down lists
    FixForDropdownListsAndTimers()
End Sub

Private Sub FixForDropdownListsAndTimers()
    ' Provcess timers
    Me.FindControls(Of System.Web.UI.Timer).ForEach(New Action(Of System.Web.UI.Timer)(AddressOf ProcessTimers))
End Sub

Private Sub ProcessTimers(ByVal t As System.Web.UI.Timer)
    t.Enabled = Not DisableTimers
End Sub

DisableTimers is set at the page level and filters down to the control so we can now disable all timers on a page when we want.

The FindControls method can find a list of all instances of a control type from an entire page, regardless of the nesting…

UPDATE: OK, so you have probably guessed that I am a complete muppet.. I have changes my UpdatePanels to UpdateMode=“Conditional” and with a few extra lines of code solved my problem the correct way! I will be keeping this little bit of code as you never know when you need to find all instances of a type of control :)… I am such a donkey…

Technorati Tags:   

Create a conversation around this article

Share on Facebook
Share on Twitter
Share on Linkdin

Read more

Martin Hinshelwood
In organizational development and team dynamics, Agile (as the Agile Manifesto delineates) and Scrum (as the Scrum Guide outlines) guide teams not by solving their problems but by illuminating the issues that demand attention. These frameworks aim to identify and spotlight the challenges within a team or organization’s processes, effectively …
Martin Hinshelwood
This week, I participated in a Scrum.org Webinar hosted by Sabrina Love (Scrum.org Product Owner) as well as my colleagues, Joanna Płaskonka, Ph.D. and Alex Ballarin to discuss the state of learning and how immersive learning is the future of training. You can watch the video below to hear what …
Martin Hinshelwood
For a long time now I have been searching for that perfect domain that epitomised the vision, the why, of what I am trying to achieve with my customers and the industry at large. Now I have found it in http://nkdagility.com
Martin Hinshelwood
At the MVP Summit I was appalled by the number of people who asked questions about new features for supporting hierarchical tasks! I shared a disgusted look with Peter Provost and we had a quick (and I mean really quick) conversation that resulted in this post. it really comes down …