Running on Empty

The few things I know, I like to share.

Creating more responsive WPF UI via Multi-Threading.

Introduction

In this article I will demonstrate a multi-threading technique to make WPF UI more response on long database or process calls.  A few things we want to keep in mind:

  • Never ever use the UI thread to make a long process call.
  • Display to the user that a long process is taking place, so the user doesn’t think your application is broken.
  • Always synch the process thread back to the UI thread after the long process call.

With these things in mind, our WPF applications will become more responsive and friendly to users.

Creating user friendly WPF.

One very clean way to display to the user that a control has items that are being refreshed on a long process is to grey it out.  I started off by disableing all the controls in the section that was being refreshed, but that simply looked ugly to me.  So instead, I tossed up a transparant rectangle instead.  This immediately gave me two benefits:

  • I no longer had to keep track of individual controls or panels to disable/enable.
  • I had much more control over the look and feel of the application, brought the sexiness back.

So this is what I have been doing, first I add a style to AppStyles.xaml.  You might recognize this from a few of my other articles, I always reuse code whenever possible.

  <Style x:Key="UserControlOverlayRectangleStyle" TargetType="{x:Type Rectangle}">
    <Setter Property="Fill" Value="#FF151515"/>
    <Setter Property="Opacity" Value="0.61"/>
  </Style>

Now, add a rectangle to your Grid/Panel/Canvas, whatever.  Notice the Rectangle is Visibility.Collapsed

<Grid>
  <!-- ListView or some other controls that I want
       to hide during the long refresh go here -->
  <Rectangle Name="ProcessingRectangle" Margin="0,0,0,0" Style="{DynamicResource UserControlOverlayRectangleStyle}" Visibility="Collapsed"/>
</Grid>

   
Multi-Threaded goodness

Create the following in your code behind.

private void PopulateControlsDuringLongRefreshCall()
{
    //Show processing
    ShowProcessing();

    ThreadStart ts = delegate
    {
        // Do long work here

        Dispatcher.BeginInvoke(DispatcherPriority.Normal, (EventHandler)
        delegate
        {
            HideProcessing();
        }, null, null);
    };
    ts.BeginInvoke(delegate(IAsyncResult aysncResult) { ts.EndInvoke(aysncResult); }, null);
}

private void ShowProcessing()
{
    ProcessingRectangle.Visibility = Visibility.Visible;
}

private void HideProcessing()
{
    ProcessingRectangle.Visibility = Visibility.Collapsed;
}

 


Conclusion

In this article I demonstrated how to use a multithreading technique to make the WPF UI more responsive during long database or processing calls.  Hopefully, you will find this useful, I have used this technique in other areas besides WPF.

Your comments and suggestions are always welcome.  Your feedback is very helpful in keeping articles up to date.

About these ads

January 11, 2008 - Posted by | C#, WPF, XAML

1 Comment »

  1. You may consider using the NotifyWorker pattern. Kevin Moore outlined it here:
    http://work.j832.com/2008/01/responsive-ui-with-unresponsive-data.html

    Comment by MattD. | August 19, 2008 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: