Posts
58
Comments
405
Trackbacks
0
Refresh / Update WPF controls

Sometime in the past, a friend asked me how to update a control to show status while his code is doing a loop of stuff.  Essentially changing the text of a label (or sophisticatedly we can say a text-based progress bar).  In my past coding with MFC and WinForms, it's fairly easy enough, you just invalidate and do an update (Invalidate / UpdateWindow in MFC or Invalidate / Update in WinForms).  This approach also coincides with how Windows UI operate, where you specify the region that needs to be redrawn and then you send a message to the message pump for that control to paint itself.

So, I expected something similar (if not exactly the same) to also be present in WPF; much to my surprise, there is no equivalent.   All my internet searches actually shows how to do this using background thread - it is the approach that needs to be taken in a proper programming context, however there are times when you just want to do something quick & dirty or you want to augment an existing app / port where you don't want to introduce new elements.  There are also considerations to be made when both UI and worker thread access the same data, especially with regard to data binding (see my post about collection change not supporting multi-threading out of the box).

So, I've decided to add a helper method to refresh a WPF control.  I really appreciated the Refresh method in WinForms (which executes both Invalidate & Update), so I'm renaming my method to be Refresh as well.  The code snippet below also show some C# specific techniques, namely: anonymous delegates and extension methods.

 

public static class ExtensionMethods

{

   private static Action EmptyDelegate = delegate() { };

 

   public static void Refresh(this UIElement uiElement)

   {
      uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
   }
}

private void LoopingMethod()

{
   for (int i = 0; i < 10; i++)
   {
      label1.Content = i.ToString();
      label1.Refresh();
      Thread.Sleep(500);
   }
}


The LoopingMethod is just the method I use in my Window class to update the label (updating the progress) and then the code does some heavy lifting (Sleep ).  The Refresh method is the extension method that takes any UI element and then calls that UIElement's Dispatcher's Invoke method.  The trick is to call the Invoke method with DispatcherPriority of Render or lower.  Since we don't want to do anything, I created an empty delegate.  So how come this achieves refresh functionality?

When the DispatcherPriority is set to Render (or lower), the code will then execute all operations that are of that priority or higher.  In the example, the code already sets label1.Content to something else, which will result in a render operation.  So by calling Dispatcher.Invoke, the code essentially asks the system to execute all operations that are Render or higher priority, thus the control will then render itself (drawing the new content).  Afterwards, it will then execute the provided delegate (which is our empty method).

Pretty weird; there was a post somewhere in my google search that led me this route, and I was surprised as to how it worked.  I couldn't find it anymore, but credit where credit is due, someone else figured out that Invoke-ing a Render or lower priority task will result in the UI being redrawn.

Update (January 20, 2009):

A Commenter asked for a full sample, so I've uploaded one here.  I don't speak Spanish, but Google translator was working great!

Update (February 26, 2009):

A Commenter asked for a VB.NET sample, so I've uploaded one here.

Update (January 13, 2010):

Apparently geekswithblogs doesn't allow linking non-image files (thus the samples link doesn't work anymore).  Samples are now being put in my Google Sites site.  C# sample here and VB.NET sample here.

posted on Monday, August 25, 2008 10:22 AM Print
Comments
Gravatar
# re: Refresh / Update WPF controls
Dolores
1/19/2009 10:26 AM
Oye podrias proporcionarme un ejemplo completo porque no he podido implementar tu pedazo de codigo en mi proyecto
Gravatar
# re: Refresh / Update WPF controls
beginner-WPF
2/26/2009 5:12 PM
hello
im very happy to write to this mail to tell im a student and i love programming and i hope to learn more about wPF and im trying to use this code in vb.net but it doesnt work or im not able to do this can you help me with lesson or a code source in vb.net language to use refresh method and thanks u so much !!
Gravatar
# re: Refresh / Update WPF controls
Rex_NFX
5/28/2009 9:34 AM
Awesome! Works beautiful. I searched a half a dozen other posts before I found this and nothing else worked. Thanks!
Gravatar
# Refresh / Update WPF controls
x
6/10/2009 4:08 AM
it not working for when u press control tab continuosly
Gravatar
# re: Refresh / Update WPF controls
Robert
7/9/2009 1:57 AM
Perfect code-snippet
Thx a lot!
Gravatar
# re: Refresh / Update WPF controls
Ken Blackstein
7/24/2009 8:32 AM
elegant.
thank you.
Gravatar
# re: Refresh / Update WPF controls
Andre
8/11/2009 8:08 AM
Thank you very much!!!
Gravatar
# re: Refresh / Update WPF controls
JBBW
8/16/2009 6:36 AM
Wow - this is great. Thank you.
Gravatar
# Re: Refresh / Update WPF controls
MrK
9/24/2009 4:08 AM
Tried this approach when doing TabControl.Items.MoveCurrentTo... and it has no effect. The tab control is still not redrawn. Any ideas? Thanks.
Gravatar
# re: Refresh / Update WPF controls
Muljadi Budiman
9/24/2009 6:57 AM
@MrK:
Please leave an email next time; it's easier than corresponding via comments.

From my simple test, there are some possibilities as to why it doesn't work for you:
1. I created a TabControl and have the TabItems in the XAML; with this scenario, MoveCurrentTo does not change the selected tab; if I call TabControl1.SelectedItem = TabControl1.Items[1] (to set it to the second item) then do TabControl1.Refresh, it works.
2. If I created the tabitems in code and put them in a CollectionView, then MoveCurrentTo will also change the SelectedItem (tab) and .Refresh will also work.
3. If you're using Windows 7 (don't know about Vista), I have to change the DispatcherPriority to Input (or lower) before it'll work.
Gravatar
# re: Refresh / Update WPF controls
kv
11/8/2009 10:47 AM
This is a great tip, thanks. It does work, but only if you have one element in the loop. If you do, for example have two labels, it will update both of them even if only calling label1.refresh();
Any ideas?
Gravatar
# re: Refresh / Update WPF controls
Juan
12/8/2009 9:00 AM
Thank you for this elegant solution. In Vista it works fine with DispatcherPriority.Render.
Gravatar
# re: Refresh / Update WPF controls
Xcalibur
12/16/2009 8:57 PM
You can use label1.InvalidateVisual(); to achieve this ...

Also im surprised you need to do any of this at all, since WPF should automatically update the UI when a dependency property is updated (which Content is)
Gravatar
# re: Refresh / Update WPF controls
Muljadi Budiman
12/17/2009 7:58 AM
To Xcalibur:

The post discusses a way to manually force a refresh on a UIElement, given that the busy-code is running on the same thread as the UI Dispatcher thread.

In Windows development, regardless of programming platform, to update a UI first you invalidate it, which means a WM_PAINT is sent over so the control can draw itself. If you're running in a single thread, there's no way to force that WM_PAINT processing in WPF (in Win32 API, usually we would call SendMessage, rather than PostMessage).

In WPF development methodology, the way to handle this correctly is to have the busy-code in a separate thread - which is the proper thing to do. However, every now and then, especially with small projects, you don't want the hassle of creating a worker thread - thus this Refresh extension method fits that bill.
Gravatar
# re: Refresh / Update WPF controls
siva
1/12/2010 7:22 PM
i cant download the attached sample here. can any one provide the link or attached file. am in urgetn need to see this article
Gravatar
# re: Refresh / Update WPF controls
HHick123
2/5/2010 9:23 PM
Hi, I just found a way (hack) to redraw the whole window using opacity... Regards, H

class DialogUtils
{

public static void Repaint(System.Windows.Window dialogWindow) //Hack using Opacity to enforce repaint
{
Double opacity = dialogWindow.Opacity;
Double newOpacity = opacity - 0.01;
if (newOpacity < 0)
newOpacity = 0.01;
dialogWindow.Opacity = newOpacity;
dialogWindow.Opacity = opacity;
dialogWindow.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (Action)delegate() { });
Window mainWindow = ((Application.Current) as MmsApp).MainWindow;
opacity = mainWindow.Opacity;
newOpacity = opacity - 0.01;
if (newOpacity < 0)
newOpacity = 0.01;
mainWindow.Opacity = newOpacity;
mainWindow.Opacity = opacity;
mainWindow.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (Action)delegate() { });
}
}
Gravatar
# re: Refresh / Update WPF controls
FelixGbk
2/15/2010 10:30 AM
That's the most elegant solution I have seen so far. Thanks! My VISTA needs at least DispatcherPriority.ContextIdle.
Gravatar
# re: Refresh / Update WPF controls
Ridley
3/16/2010 12:22 PM
I just wanted to say... thank you so much. I had so much trouble updating my WPF UI until I found your article. I tried a number of solutions, almost none of which actually worked. (Some were just too complicated to justify trying). Anyway, thanks a ton!
Gravatar
# re: Refresh / Update WPF controls
Mike T
5/19/2010 5:14 AM
Thanks, thanks, thanks - this is brilliant !!!
Gravatar
# re: Refresh / Update WPF controls
Poppo
7/21/2010 6:46 PM
Thank you for your great sample code. I was searching how to refresh my controls, but I couldn't find any answer. When I saw your site, I was very surprised that there is no refresh command in WPF, too. Anyway, thank you so much your solution.
Gravatar
# re: Refresh / Update WPF controls
Ash
7/28/2010 4:48 AM
Thanks for the extension method, works perfectly cheers.
Gravatar
# re: Refresh / Update WPF controls
Nitin
7/28/2010 4:34 PM
HI HHick123, I am getting build error on MmsApp. ==>The type or namespace name 'MmsApp' could not be found (are you missing a using directive or an assembly reference)

Any idea.
Gravatar
# re: Refresh / Update WPF controls
Dennis Schaefer
8/12/2010 7:06 AM
This approach has already saved me a great deal of time! It also works well for updating progress bars when the percent changes. The multithread method is great if you need to keep working inside the GUI while a long-running process does its thing, but where all you want is PROGRESS from a long-running task, this fills the bill like crazy!
Gravatar
# re: Refresh / Update WPF controls
Jason Sypkens
9/9/2010 1:22 PM
Thanks... worked like a charm.
Gravatar
# re: Refresh / Update WPF controls
Paul Hartzer
10/17/2010 9:39 AM
Here's another grateful commenter. I've been searching for this for a bit now, and have finally found it! All I wanted was a dialog box to pop up and tell the user to be patient, so this suited the bill perfectly.
Gravatar
# re: Refresh / Update WPF controls
macro
11/9/2010 9:53 PM
While I running the C# code on windows 7, it cann't work!
the value of label begin with 0 and jump to 1, but after that it jump to 9,
I don't know if the method is useful in windows 7?
Gravatar
# Sorry, does not work
Robert
11/22/2010 8:32 PM
Sorry, this does not do anything. The GUI is not rendered while the click handler for my button is running ~1-2 seconds.
The GUI is not rendered during this time, although I do the refresh on the window.
Gravatar
# re: Refresh / Update WPF controls
Declic
11/29/2010 2:49 AM
On Windows 7 you need :
uiElement.Dispatcher.Invoke(DispatcherPriority.ContextIdle, EmptyDelegate);
Gravatar
# re: Refresh / Update WPF controls
adult toys
11/29/2010 4:29 PM
I have been through the whole content of this blog which is very informative and knowledgeable stuff, I would like to visit again. Thanks for sharing.

Gravatar
# re: Refresh / Update WPF controls
shihab
11/29/2010 8:19 PM
Cool, it works. Thanks.
Gravatar
# re: Refresh / Update WPF controls
Kaplan
12/30/2010 9:01 PM
Works fine. Thanks.
Gravatar
# re: Refresh / Update WPF controls
mke
3/17/2011 3:10 AM
what about if you use MVVM and you want to update the label in the ViewModel? All you got is a string property bound to the label. Let's say you want the label to say "Save Started" //do save then "Sae Completed"?
Gravatar
# re: Refresh / Update WPF controls
Jose Luis Suarez
4/29/2011 5:39 PM
Powerful function. It saved me =) . Could you explain how it works. I have never seen code like that
Gravatar
# re: Refresh / Update WPF controls
tim
5/9/2011 12:36 PM
What is EmptyDelegate?
Gravatar
# re: Refresh / Update WPF controls
ohmusama
5/11/2011 3:34 AM
You have some things backwards, the empty delegate goes first, then the dispatcherPriority:


Action emptyDelegate = delegate { };
mazeCanvas.Dispatcher.Invoke(emptyDelegate, DispatcherPriority.Render);
Gravatar
# re: Refresh / Update WPF controls
kevgig
6/1/2011 7:55 AM
exactly what I was looking for!
Thanks!
Gravatar
# re: Refresh / Update WPF controls
Scott
6/14/2011 4:00 AM
Excellent post, answered my question immediately. :)
Gravatar
# re: Refresh / Update WPF controls
Bob
6/22/2011 9:22 PM
Simple and effective. Thanks a lot.
Gravatar
# re: Refresh / Update WPF controls
Aaron
8/28/2011 2:50 PM
Thanks so much! This post saved my day!
Gravatar
# re: Refresh / Update WPF controls
Prakash Muniyappa
9/26/2011 7:16 AM
You guys are giants, and we stand on your shoulders!
Plenty of Thanks!!
Gravatar
# re: Refresh / Update WPF controls
JMA
10/5/2011 2:40 AM
THANK YOU THANK YOU THANK YOU
Gravatar
# re: Refresh / Update WPF controls
Anthony
10/11/2011 2:48 PM
Seemed to fix my VSTO bug.
Thanks
http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/3adc00cc-b2c2-4dc5-a0e2-f08f68190d53
Gravatar
# re: Refresh / Update WPF controls
Louis Vuitton Outlet
11/7/2011 1:52 PM
exit d' machine d' trainer was available to coachdiscountstore.us. Blue black CH-0299Author of bag d' packing of signature of Madison d' trainer
Gravatar
# re: Refresh / Update WPF controls
Luis Oliveira
11/12/2011 5:45 PM
Really usefull to me, I think is the same thing for all, your extension will solve a lot of head pains!
Gravatar
# re: Refresh / Update WPF controls
Igor
11/16/2011 5:35 AM
U saved my day , thanks!
Gravatar
# re: Refresh / Update WPF controls
makcura
11/25/2011 12:38 AM
Thanks, it was very helpfull to me.
Gravatar
# re: Refresh / Update WPF controls
umair
11/30/2011 4:54 AM
Thanks .. its works really well ...
Gravatar
# re: Refresh / Update WPF controls
armhidden
1/4/2012 2:56 PM
Not understands. what isn't use?
Gravatar
# re: Refresh / Update WPF controls
Lane Buckingham
1/24/2012 5:25 AM
I found that if you include a timeout it is even more responsive. Like this: uiElement.Dispatcher.Invoke(EmptyDelegate, new TimeSpan(0, 0, 0, 0, 50), DispatcherPriority.Render, new object[] {});
Gravatar
# re: Refresh / Update WPF controls
Stephen
2/27/2012 8:09 PM
It's Work for me.. fine .. Thank you ..
Gravatar
# re: Refresh / Update WPF controls
Eric Ouellet
3/29/2012 6:44 AM
Not perfect !
It work fine in general i'm sure. But it has its flaws.
First, it redraw everything, not only the control you wish. Second it could easily crash in a regular WPF app where the wanted refresh happen in an observable collection collection change event and the Refresh need to use the collection (iterate into it).
But thanks ! Great to know !
Gravatar
# re: Refresh / Update WPF controls
Kavya
5/1/2012 5:45 PM
Thank you :)
Gravatar
# re: Refresh / Update WPF controls
programmer
5/8/2012 6:52 PM
thx that is a very very very practical method, very useful
Gravatar
# re: Refresh / Update WPF controls
Bite.Me
6/5/2012 12:04 AM
Dude, I need to confess my undying love for you right now. Took me forever to find a solution and this worked in 5 minutes. Awesomeness :D
Gravatar
# re: Refresh / Update WPF controls
Karthik
6/19/2012 12:30 AM
I think the best practice would be to do the looping(cpu intensive work) on a seperate thread, and call Dispatcher.BeginInvoke from that thread to update the UI. Anyways I stumbled upon this article trying to find out a way to force draw a window(a WPF window) without actually opening the window, if you know about this please write to me. Thanks :)
Gravatar
# Abhishek Birdawde
Abhishek
8/29/2012 6:13 AM
Thank you man...i was searching this for long time but your solution worked...thanks a lot..
Gravatar
# re: Refresh / Update WPF controls
Abhishek
9/24/2012 12:52 PM
Loved this post... Searching for it from a long time ... InvalidateVisual() didn't work for me ... N I was not interested in threading..
this solution worked perfectly.. Thank you :)
Gravatar
# re: Refresh / Update WPF controls
Sven
1/21/2013 10:20 PM
It's working perfectly!! Thank you!
Gravatar
# sigh...
.....
1/28/2013 7:06 PM
fuck this, does not work at all. Still don't know why Microsoft could not just add a refresh to a control.
Gravatar
# re: Refresh / Update WPF controls
Nitro
1/28/2013 11:00 PM
Thanks, great help for batch operations on UI
Gravatar
# re: Refresh / Update WPF controls
Klemens
3/27/2013 3:29 AM
Wow, that worked perfectly for me! Thanks a lot, great job!
Gravatar
# re: Refresh / Update WPF controls
Key Lawson
4/1/2013 8:47 AM
If I place your code outside the 'public partial class', I get "DispatcherPriority does not exist in the current context". If I place your code inside, I get "Extension methods M/B defined in a top level static class; ExtensionMethods is a nested class". Any advice?
I am definitely a newbie to C# and WPF.
Gravatar
# re: Refresh / Update WPF controls
Yashin
4/24/2013 11:22 PM
Thanks for the help. I now also have an idea of what an Extension method is.
Gravatar
# re: Refresh / Update WPF controls
Rima
6/17/2013 6:58 PM
Thank you so very much..! Its been a great help..!!
Gravatar
# re: Refresh / Update WPF controls
Hannes
7/9/2013 8:18 PM
Crazy. That really works! I was looking for quite a few solutions. There might be better ways, but this does the job :)
THX
Gravatar
# re: Refresh / Update WPF controls
Normen
9/1/2013 8:11 AM
Thank you very much for this useful code. It saves me a lot of time.
Gravatar
# re: Refresh / Update WPF controls
ThierryPechoux
9/2/2013 6:17 AM
Very very nice.
Thx
Gravatar
# re: Refresh / Update WPF controls
Mohamed
1/22/2014 5:56 PM
It's around 5 years and people still benefiting from your help and i am no exception.

I wanted to say thanks then I saw all of these comments. But still you deserve more thanks. You solved a nightmare to me.
Gravatar
# re: Refresh / Update WPF controls
Helen Trim
6/12/2014 10:10 PM
I have just used this and it solves a problem I have been struggling with. Thank you.
Gravatar
# re: Refresh / Update WPF controls
Boon Yar Toh
6/30/2014 2:21 PM
Thank you for this post. I finally found this solution (after 2 days of hard searching) to extend the refresh method for my text box in vb!! cheers
Gravatar
# re: Refresh / Update WPF controls
David
8/5/2014 9:17 PM
Thank you very much. It is really working on my card game where the dealer send card to the players
Gravatar
# re: Refresh / Update WPF controls
sashaizrussi
9/7/2014 12:16 AM
Works well in my simple app in VB WPF (Win 7). Are there any drawbacks ?

Post Comment

Title *
Name *
Email
Comment *