Geeks With Blogs
New Things I Learned

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 WPF , .NET | Back to top


Comments on this post: Refresh / Update WPF controls

# re: Refresh / Update WPF controls
Requesting Gravatar...
Oye podrias proporcionarme un ejemplo completo porque no he podido implementar tu pedazo de codigo en mi proyecto
Left by Dolores on Jan 19, 2009 10:26 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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 !!
Left by beginner-WPF on Feb 26, 2009 5:12 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Awesome! Works beautiful. I searched a half a dozen other posts before I found this and nothing else worked. Thanks!
Left by Rex_NFX on May 28, 2009 9:34 AM

# Refresh / Update WPF controls
Requesting Gravatar...
it not working for when u press control tab continuosly
Left by x on Jun 10, 2009 4:08 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Perfect code-snippet
Thx a lot!
Left by Robert on Jul 09, 2009 1:57 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
elegant.
thank you.
Left by Ken Blackstein on Jul 24, 2009 8:32 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you very much!!!
Left by Andre on Aug 11, 2009 8:08 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Wow - this is great. Thank you.
Left by JBBW on Aug 16, 2009 6:36 AM

# Re: Refresh / Update WPF controls
Requesting Gravatar...
Tried this approach when doing TabControl.Items.MoveCurrentTo... and it has no effect. The tab control is still not redrawn. Any ideas? Thanks.
Left by MrK on Sep 24, 2009 4:08 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
@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.
Left by Muljadi Budiman on Sep 24, 2009 6:57 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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?
Left by kv on Nov 08, 2009 10:47 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you for this elegant solution. In Vista it works fine with DispatcherPriority.Render.
Left by Juan on Dec 08, 2009 9:00 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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)
Left by Xcalibur on Dec 16, 2009 8:57 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Muljadi Budiman on Dec 17, 2009 7:58 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
i cant download the attached sample here. can any one provide the link or attached file. am in urgetn need to see this article
Left by siva on Jan 12, 2010 7:22 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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() { });
}
}
Left by HHick123 on Feb 05, 2010 9:23 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
That's the most elegant solution I have seen so far. Thanks! My VISTA needs at least DispatcherPriority.ContextIdle.
Left by FelixGbk on Feb 15, 2010 10:30 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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!
Left by Ridley on Mar 16, 2010 12:22 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks, thanks, thanks - this is brilliant !!!
Left by Mike T on May 19, 2010 5:14 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Poppo on Jul 21, 2010 6:46 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks for the extension method, works perfectly cheers.
Left by Ash on Jul 28, 2010 4:48 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Nitin on Jul 28, 2010 4:34 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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!
Left by Dennis Schaefer on Aug 12, 2010 7:06 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks... worked like a charm.
Left by Jason Sypkens on Sep 09, 2010 1:22 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Paul Hartzer on Oct 17, 2010 9:39 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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?
Left by macro on Nov 09, 2010 9:53 PM

# Sorry, does not work
Requesting Gravatar...
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.
Left by Robert on Nov 22, 2010 8:32 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
On Windows 7 you need :
uiElement.Dispatcher.Invoke(DispatcherPriority.ContextIdle, EmptyDelegate);
Left by Declic on Nov 29, 2010 2:49 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.

Left by adult toys on Nov 29, 2010 4:29 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Cool, it works. Thanks.
Left by shihab on Nov 29, 2010 8:19 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Works fine. Thanks.
Left by Kaplan on Dec 30, 2010 9:01 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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"?
Left by mke on Mar 17, 2011 3:10 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Powerful function. It saved me =) . Could you explain how it works. I have never seen code like that
Left by Jose Luis Suarez on Apr 29, 2011 5:39 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
What is EmptyDelegate?
Left by tim on May 09, 2011 12:36 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
You have some things backwards, the empty delegate goes first, then the dispatcherPriority:


Action emptyDelegate = delegate { };
mazeCanvas.Dispatcher.Invoke(emptyDelegate, DispatcherPriority.Render);
Left by ohmusama on May 11, 2011 3:34 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
exactly what I was looking for!
Thanks!
Left by kevgig on Jun 01, 2011 7:55 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Excellent post, answered my question immediately. :)
Left by Scott on Jun 14, 2011 4:00 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Simple and effective. Thanks a lot.
Left by Bob on Jun 22, 2011 9:22 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks so much! This post saved my day!
Left by Aaron on Aug 28, 2011 2:50 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
You guys are giants, and we stand on your shoulders!
Plenty of Thanks!!
Left by Prakash Muniyappa on Sep 26, 2011 7:16 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
THANK YOU THANK YOU THANK YOU
Left by JMA on Oct 05, 2011 2:40 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Seemed to fix my VSTO bug.
Thanks
http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/3adc00cc-b2c2-4dc5-a0e2-f08f68190d53
Left by Anthony on Oct 11, 2011 2:48 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
exit d' machine d' trainer was available to coachdiscountstore.us. Blue black CH-0299Author of bag d' packing of signature of Madison d' trainer
Left by Louis Vuitton Outlet on Nov 07, 2011 1:52 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Really usefull to me, I think is the same thing for all, your extension will solve a lot of head pains!
Left by Luis Oliveira on Nov 12, 2011 5:45 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
U saved my day , thanks!
Left by Igor on Nov 16, 2011 5:35 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks, it was very helpfull to me.
Left by makcura on Nov 25, 2011 12:38 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks .. its works really well ...
Left by umair on Nov 30, 2011 4:54 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Not understands. what isn't use?
Left by armhidden on Jan 04, 2012 2:56 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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[] {});
Left by Lane Buckingham on Jan 24, 2012 5:25 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
It's Work for me.. fine .. Thank you ..
Left by Stephen on Feb 27, 2012 8:09 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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 !
Left by Eric Ouellet on Mar 29, 2012 6:44 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you :)
Left by Kavya on May 01, 2012 5:45 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
thx that is a very very very practical method, very useful
Left by programmer on May 08, 2012 6:52 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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
Left by Bite.Me on Jun 05, 2012 12:04 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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 :)
Left by Karthik on Jun 19, 2012 12:30 AM

# Abhishek Birdawde
Requesting Gravatar...
Thank you man...i was searching this for long time but your solution worked...thanks a lot..
Left by Abhishek on Aug 29, 2012 6:13 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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 :)
Left by Abhishek on Sep 24, 2012 12:52 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
It's working perfectly!! Thank you!
Left by Sven on Jan 21, 2013 10:20 PM

# sigh...
Requesting Gravatar...
fuck this, does not work at all. Still don't know why Microsoft could not just add a refresh to a control.
Left by ..... on Jan 28, 2013 7:06 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks, great help for batch operations on UI
Left by Nitro on Jan 28, 2013 11:00 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Wow, that worked perfectly for me! Thanks a lot, great job!
Left by Klemens on Mar 27, 2013 3:29 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Key Lawson on Apr 01, 2013 8:47 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thanks for the help. I now also have an idea of what an Extension method is.
Left by Yashin on Apr 24, 2013 11:22 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you so very much..! Its been a great help..!!
Left by Rima on Jun 17, 2013 6:58 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Crazy. That really works! I was looking for quite a few solutions. There might be better ways, but this does the job :)
THX
Left by Hannes on Jul 09, 2013 8:18 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you very much for this useful code. It saves me a lot of time.
Left by Normen on Sep 01, 2013 8:11 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Very very nice.
Thx
Left by ThierryPechoux on Sep 02, 2013 6:17 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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.
Left by Mohamed on Jan 22, 2014 5:56 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
I have just used this and it solves a problem I have been struggling with. Thank you.
Left by Helen Trim on Jun 12, 2014 10:10 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
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
Left by Boon Yar Toh on Jun 30, 2014 2:21 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Thank you very much. It is really working on my card game where the dealer send card to the players
Left by David on Aug 05, 2014 9:17 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Works well in my simple app in VB WPF (Win 7). Are there any drawbacks ?
Left by sashaizrussi on Sep 07, 2014 12:16 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
How can we do this from static method?
Left by sager on Feb 03, 2015 8:05 PM

# re: Refresh / Update WPF controls
Requesting Gravatar...
You are my hero.
Left by lamke on Mar 03, 2015 9:40 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Nicely done. Handles this scenario perfectly.
Left by Locke on Mar 24, 2015 1:52 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
OH
MY
GOD!

This is fantastic. After digging through like two dozen Q&A posts with all sorts of engrossing details about threads and asynchronous and a dozen different ways of merely having a textbox I've changed the text of update immediately, before the method call than takes several seconds to run - I finally stumble onto The Beautiful Answer you provide.

Thank you!
Left by Steve Greene on Jul 16, 2015 11:19 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
I have tried for hours to solve a problem with my status bar text not updating on my WPF window. I put your small bit of code in place, then called the Refresh of the text and voila!! It worked!! Thank you so much. I am so happy I found this solution.
Left by Joyce Kinzler on Aug 12, 2015 2:15 AM

# re: Refresh / Update WPF controls
Requesting Gravatar...
Excellent!, Perfect solution,

Thank you.
Left by Karthikeyan on Aug 28, 2015 9:36 PM

Your comment:
 (will show your gravatar)


Copyright © Muljadi Budiman | Powered by: GeeksWithBlogs.net | Join free