Monday, September 07, 2009

Updating the UI from a BackgroundWorker in WPF

This approach enabled me to flexibly send messages to objects on the UI thread while processing from a BackgroundWorker object in WPF. Otherwise, the UI thread doesn't update if the BackgroundWorker code tries to manipulate its objects during processing. First I created this UIUpdater:
public delegate void UpdateTextDelegate(string message);

/// Sends messages to the UI thread via the dispatcher.

class UIUpdater
#region ctor
/// Initializes a new instance of the class.

/// The dispatcher in scope for the UI.
/// Function that will apply the message to the appropriate control(s).
public UIUpdater(Dispatcher uiDispatcher, UpdateTextDelegate uiUpdateDelegate)
if (default(Dispatcher) == uiDispatcher) throw new ArgumentNullException("uiDispatcher");
if (default(UpdateTextDelegate) == uiUpdateDelegate) throw new ArgumentNullException("uiUpdateDelegate");

dispatcher = uiDispatcher;
updateTextDelegate = uiUpdateDelegate;

#region member variables
Dispatcher dispatcher = default(Dispatcher);
UpdateTextDelegate updateTextDelegate = default(UpdateTextDelegate);

#region methods
/// Sends the message.

/// The message.
public void SendMessage(string message)
if (default(string) == message) throw new ArgumentNullException("message"); // allow string.Empty
(ThreadStart)delegate() {

To use it, in the BackgroundWorker_DoWork event handler, initialize it and pass it into your objects that implement the background work. Give it a reference to your dispatcher and a delegate that will handle updates from the background thread:
UIUpdater updater = new UIUpdater(mainWindow.Dispatcher, new UpdateTextDelegate(UpdateStatus));

Then from the code doing the background work, you can call the SendMessage delegate to safely pass along the message:
updater.SendMessage("Deleting all items from the " + listName + " list...");

No comments:

Post a Comment