Tuesday, August 30, 2011

Update the WPF UI now: how to wait for the rendering to finish ?

WPF is really awesome to build reactive applications and data binding is here to push useful information inside of the User Interface. All is done magically and it’s wonderfully simple to create an application without knowledge of the internals of the WPF’s rendering.

Now, I wan’t to talk about something which can useful in every WPF application : how to wait for the rendering UI to be done. This can also be rephrased to : “how to force the rendering after I performed an action ?“.

Why would I need this ?

You can find a lot of reasons to need this:

    You are doing a long-running job that can only be done on the UI thread (good bye BackgroundWorker) and you want to tell the user the progress of the task.
    The rendering of a control takes a lot of time to be done and you want to be sure that the “wait please” Textblock” is rendered instead of a white screen.
    You need to wait that the UI rendering following an action is done.
    You are a geek and you want to know how you can do this !
    You are adding a lot of items to a binded collection and you want to wait for the rendering of each added item to be done. By doing this, the data won’t seems to be push into the ItemsControl by packet but one by one. No apparent freeze of the UI. As pointed out by a lot of people, there is really better ways to do this.

Here is a non-exhaustive list of things that can only be done on the UI-Thread and which are time-consuming (if you have some others, please give me them in the comments):

    Create UI controls may be long(exemple),
    Im my previous project using Mogre 3D, I needed to initialize some parts of the 3D engine in the main UI Thread,
    Sometimes applying the content to a view is very long because the XAML is really complex (more to come on this in a later post),

Please tell me how can I do this !

What is wonderful is that the solution takes only one little line of code. One line of code.

To keep it simple, the rendering of the UI is perform on the UI thread via the Dispatcher. It can be considered as a tasks processer, each of these task being assigned a priority. The rendering of the UI is one of these tasks and all you have to do is tell the Dispatcher: “perform an action now with a priority less than the rendering”. The current work will then wait for the rendering to be done.

Here is the snippet this sentence transposing in .Net:

Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null);

Read more: Yet another blog about
QR: https://chart.googleapis.com/chart?chs=80x80&cht=qr&choe=UTF-8&chl=http://www.jonathanantoine.com/2011/08/29/update-my-ui-now-how-to-wait-for-the-rendering-to-finish/

Posted via email from Jasper-Net