Lars Holm Jensen's Code Blog

Just another WordPress codeblog on C#, Silverlight and all things .NET

Archive for the ‘timer’ tag

FocusHelper

with one comment

Here is a little helper class I use when implementing tab navigation in Silverlight. When FocusHelper.Start() is called at application startup it simply creates a timer which attempts to give the focused element a red border and a slightly red background. When I say attempts it’s because themes and styles may prevent the changes from showing. I have often found it helpful, because it is almost never clear which element in Silverlight has the focus. Notice that the functionality is disabled if your browser’s zoom is different from 100%.

public static class FocusHelper
{
    public static void Start()
    {
        focusBorderBrush = new SolidColorBrush(Colors.Red);
        focusBackground = new SolidColorBrush(Colors.Red);
        focusBackground.Opacity = 0.1;
 
        focusTimer = new Timer(new TimerCallback((o) =>
        {
            try
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    object temp = null;
 
                    if (System.Windows.Application.Current.Host.Content.ZoomFactor==1)
                        temp = FocusManager.GetFocusedElement();
 
                    if (temp != lastFocus)
                    {
                        if (temp is Control)
                        {
                            //Give the last control back its original color
                            if (lastFocus != null)
                            {
                                lastFocus.BorderBrush = lastBrush;
                                lastFocus.BorderThickness = lastThickness;
                                lastFocus.Background = lastBackground;
                            }
 
                            lastFocus = temp as Control;
                            lastBrush = lastFocus.BorderBrush;
                            lastThickness = lastFocus.BorderThickness;
                            lastBackground = lastFocus.Background;
 
                            lastFocus.BorderBrush = focusBorderBrush;
                            lastFocus.BorderThickness = new Thickness(1);
                            lastFocus.Background = focusBackground;
                        }
                    }
                });
            }
            catch
            {
            }
 
        }), null, 0, 100);
    }
 
    private static System.Threading.Timer focusTimer;
    private static Control lastFocus = null;
    private static Thickness lastThickness;
    private static Brush lastBrush;
    private static Brush lastBackground;
    private static Brush focusBorderBrush;
    private static Brush focusBackground;
}

Written by larsholm

December 16th, 2009 at 6:46 pm

PostponingTimer

with one comment

This is a small timer class that I have found useful a couple of times.

It takes a job and a timeout in its Run() method, which it executes

after the timeout, unless you call the Run() method again, in which

case it postpones the execution of the job. I have mostly used this

in connection with some type of user input. For instance, doing

something when there has been a sufficient pause in scrolling or typing.

 

/// <summary>

/// This class can be used to execute a job just once after a specified

/// time since the last of a series of events has fired.

/// For instance, when implementing an Auto-Save feature in a textbox you

/// might want to avoid saving on every keypress event. In this case you can

/// call Run(() => Save(), 5000) in each keypress event. The PostPoningTimer

/// will then make sure that Save() is executed one time when 5 seconds has

/// past since the last keypress event. Any new keypresses will of course

/// repeat the process.

/// </summary>

public class PostponingTimer

{

    private Timer timer;

 

    private Dispatcher CurrentDispatcher

    {

        get

        {

#if SILVERLIGHT

            return System.Windows.Deployment.Current.Dispatcher;

#else

            return Dispatcher.CurrentDispatcher;

#endif

        }

    }

 

    private void Execute(Action job, Dispatcher dispatcher)

    {

#if SILVERLIGHT

        dispatcher.BeginInvoke(job);

#else

        dispatcher.Invoke(job);

#endif

    }

 

    /// <summary>

    /// If you keep calling Run() within timeout, job never gets executed.

    /// Only when you stop calling Run() job will run once after timeout

    /// milliseconds.

    /// <para>Job will run on calling threads dispatcher. If in silverlight

    /// the UI threads dispatcher is used.</para>

    /// </summary>

    /// <param name=”job”></param>

    /// <param name=”timeout”></param>

    public void Run(Action job, int timeout)

    {

        //Make sure the timer from last call is prevented from running.

        if (timer != null) timer.Dispose();

 

        //When not in SILVERLIGHT the line below makes sure to use the

        //dispatcher of the calling thread.

        //In silverlight the UI thread dispatcher is used.

        Dispatcher dispatcher = CurrentDispatcher;

 

        timer = new Timer(new TimerCallback((o) =>

            {

                Execute(job, dispatcher);

            }), null, timeout, Timeout.Infinite);

    }

 

    /// <summary>

    /// If you keep calling Run() within timeout, job never gets executed.

    /// Only when you stop calling Run() job will run once after timeout

    /// milliseconds.

    /// <para>Job will run on the timer’s thread.</para>

    /// </summary>

    /// <param name=”job”></param>

    /// <param name=”timeout”></param>

    public void RunNonUI(Action job, int timeout)

    {

        //Make sure the timer from last call is prevented from running.

        if (timer != null) timer.Dispose();

 

        timer = new Timer(new TimerCallback((o) =>

            {

                job();

            }), null, timeout, Timeout.Infinite);

    }

 

    /// <summary>

    /// If you keep calling Run() within timeout, job never gets executed.

    /// Only when you stop calling Run() job will run once after timeout

    /// milliseconds.

    /// <para>Actions will run on calling threads dispatcher. If in

    /// silverlight the UI threads dispatcher is used.</para>

    /// </summary>

    /// <param name=”job”></param>

    /// <param name=”timeout”></param>

    /// <param name=”callback”></param>

    public void Run(Action job, int timeout, Action callback)

    {

        //Make sure the timer from last call is prevented from running.

        if (timer != null) timer.Dispose();

 

        //When not in SILVERLIGHT the line below makes sure to use the

        //dispatcher of the calling thread.

        //In silverlight the UI thread dispatcher is used.

        Dispatcher dispatcher = CurrentDispatcher;

 

        timer = new Timer(new TimerCallback((o) =>

            {

                Execute(job + callback, dispatcher);

            }), null, timeout, Timeout.Infinite);

    }

 

    /// <summary>

    /// If you keep calling Run() within timeout, job never gets executed.

    /// Only when you stop calling Run() job will run once after timeout

    /// milliseconds.

    /// <para>Actions will run on the timer’s thread.</para>

    /// </summary>

    /// <param name=”job”></param>

    /// <param name=”timeout”></param>

    /// <param name=”callback”></param>

    public void RunNonUI(Action job, int timeout, Action callback)

    {

        //Make sure the timer from last call is prevented from running.

        if (timer != null) timer.Dispose();

 

        timer = new Timer(new TimerCallback((o) =>

            {

                (job + callback)();

            }), null, timeout, Timeout.Infinite);

    }

 

}

Written by larsholm

December 16th, 2009 at 12:55 am

Posted in .NET,Silverlight

Tagged with , , , , , , ,