Click here to Skip to main content
Click here to Skip to main content

Creating a responsive UI in WPF

By , 28 Apr 2011
 

Introduction

The download contains three simple examples of implementing a responsive multi-thread WPF UI. Two examples uses the Dispstch.Invoke() method and one uses the Background WorkerTheead class and the ProcessBar UI. I’m a newbie… and probably will not be able to answer any follow-up questions. The code is simple and intuitive. Its only purpose is to give other newbies a good start, in how to implement responsive multi-thread UI.

  • Project StopWatch: is a technique for recursively calling the Dispatch of a worker thread.
  • Project WpfDispatch: is a technique using a sample Dispatch call to the main thread
  • Project WpfBackgrd: is a technique in using the Background Worker thread, note only the ProcessBar is updated.

The code behind snippets below are listed for your inspection, to determine whether, or not, you want to download the projects zip.

StopWatch C# code

using System;
using System.Threading;
using System.Windows;
using System.Windows.Threading;

namespace StopWatch
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private int iTimeMax;
        private int CurrCount;
        private bool _go = false;
        private bool countdown = false;
        private delegate void WatchDegete();

        public Window1() : base()
        {
            InitializeComponent();
        }

        #region UI Events
        public void StartOrStop(object sender, RoutedEventArgs e)
        {
            if (countdown)
            {
                countdown = false;
                startStopButton.Content = "Resume";
            }
            else
            {
                countdown = true;
                Comment.Text = "RUNNING...";
                startStopButton.Content = "Stop";
                if (!_go)
                {
                    outputBox.Text = inputBox.Text;
                    _go = true;
                }
                string[] arr = outputBox.Text.Split(':');
                CurrCount = (int.Parse(arr[0]) * 60 + int.Parse(arr[1])) * 1000;

                startStopButton.Dispatcher.BeginInvoke(
                    DispatcherPriority.Normal,
                    new WatchDegete(Clock));
            }
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            _go = false;
            countdown = false;
            Comment.Text = "READLY";
            outputBox.Text = null;
            startStopButton.Content = "Start";


        }

        private void Clock()
        {
            if (!countdown) return;
            Thread.Sleep(1000);
            CurrCount -= 1000;
            if (CurrCount <= 0)
            {
                _go = false;
                countdown = false;
                Comment.Text = "READLY";
                startStopButton.Content = "Start";
                outputBox.Text = null;
                System.Console.Beep(3000, 1000);
                MessageBox.Show("TimeOut: exceeded Time alotment!");
            }
            else
            {
                int ms = CurrCount / 1000;
                int minutes = ms / 60;
                int seconds = ms % 60;

                outputBox.Text = minutes + ":" +
                    string.Format("{0:D2}", seconds);

                startStopButton.Dispatcher.BeginInvoke(
                    DispatcherPriority.SystemIdle,
                    new WatchDegete(Clock));
            }
        }
        #endregion
    }
}

WpfDispatch C# code

using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace WpfDispatch
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private bool ready = true;
        private Thread workerThread;

        public Window1()
        {
            InitializeComponent();
        }

        private void start_Click(object sender, RoutedEventArgs e)
        {
            ready = false;
            workerThread = new Thread(DoWork);
            workerThread.Start();
        }

        private void stop_Click(object sender, RoutedEventArgs e)
        {
            ready = true;
            workerThread.Join();
        }

        private void Window_Closing(object sender,

 System.ComponentModel.CancelEventArgs e)
        {
            if (!ready)
            {
                MessageBox.Show("Stop the clock process");
                e.Cancel = true;
            }
        }

        private delegate void updateControlDelegate(Control ui, String text);

        private void updateControl(Control ui, String text)
        {
            Label l = ui as Label;
            l.Content = text;
        }

        private void DoWork()
        {
            updateControlDelegate c = updateControl;
            while (!ready)
            {
                Dispatcher.Invoke( c, label1,  DateTime.Now.ToLongTimeString());
                Thread.Sleep(200);
            }

            label1.Dispatcher.BeginInvoke(c, label1, "STOPPED");
        }
    }
}

WpfBackgrd C# code

using System.Windows;
using System.Threading;
using System.ComponentModel;

namespace WpfBackGrd
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private BackgroundWorker _worker;

        public Window1()
        {
            InitializeComponent();
        }

        private void start_Click(object sender, RoutedEventArgs e)
        {
            _worker = new BackgroundWorker();

            _worker.WorkerReportsProgress = true;
            _worker.WorkerSupportsCancellation = true;

            _worker.DoWork += delegate(object s, DoWorkEventArgs args)
            {
                BackgroundWorker worker = s as BackgroundWorker;

                for (int i = 0; i < 10; i++)
                {
                    if (worker.CancellationPending)
                    {
                        args.Cancel = true;
                        return;
                    }

                    Thread.Sleep(1000);
                    worker.ReportProgress(i + 1);
                }

                System.Console.Beep(8000, 1000);
            };

            _worker.ProgressChanged += delegate(object s,
                    ProgressChangedEventArgs args)
            {
                progressBar1.Value = args.ProgressPercentage;
            };

            _worker.RunWorkerCompleted += delegate(object s,
                    RunWorkerCompletedEventArgs args)
            {
                start.IsEnabled = true;
                cancel.IsEnabled = false;
                progressBar1.Value = 0;
            };

            _worker.RunWorkerAsync();
            start.IsEnabled = false;
            cancel.IsEnabled = true;
        }

        private void cancel_Click(object sender, RoutedEventArgs e)
        {
            _worker.CancelAsync();
        }
    }
}

License

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

About the Author

King Coffee
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
AnswerAgain, the purpose of this article is...memberKing Coffee20 Jul '11 - 15:41 
GeneralMy vote of 1memberFlorian Greinacher29 Apr '11 - 3:14 
General[My vote of 1] PoormemberMember 456543329 Apr '11 - 2:43 
General[My vote of 1] Article is not clear/not detailmemberVenkatesh Mookkan28 Apr '11 - 16:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 28 Apr 2011
Article Copyright 2011 by King Coffee
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid