WPF forcing redraw of canvas
Asked Answered
P

4

17

Okay, in windows forms you can use .refresh() to cause a redraw event on an element. Is there a similar solution in WPF?

An explanation of what I'm doing, I'm drawing a maze on a canvas object, and would like to watch as the maze is drawn (so I can see progress) instead of waiting 28 min for a solution to suddenly appear. I am drawing blocks on the canvas with a series of Rectangles. Should the refresh be on the rectangle or the canvas?

Here is a recent output: https://i.sstatic.net/ZNAdQ.jpg

I'd like a solution in c# if that is possible. Thanks.

Parole answered 11/5, 2011 at 4:21 Comment(0)
B
12

You probably want to use the Dispatcher object. I suggest you take a look a this Shawn Wildermuth's article: Build More Responsive Apps With The Dispatcher (MSDN magazine October 2007).

Bolection answered 11/5, 2011 at 5:38 Comment(5)
This wasn't 100% the solution, but it started me in the right direction. This is ultimately what worked: canvas.Dispatcher.Invoke(emptyDelegate, DispatcherPriority.Render); where emptyDelegate is Action emptyDelegate = delegate { };Parole
Thanks, Simon, for the edit you made earlier today. I am reading the article now.Locklin
The link to "Build More Responsive Apps With the Dispatcher" no longer works.Enchain
It works, but you'll have to browse to year 2007 and click October. I didn't put the exact link (plus it's a CHM) on purpose to avoid future broken links.Bolection
@Parole - TIL Dispatcher.Invoke() has 17 overloads 😂Chrysotile
M
40

This is what you are looking for...

element.InvalidateVisual();
Mispleading answered 22/3, 2012 at 10:53 Comment(0)
D
18

this work for me...

element.UpdateLayout();
Debussy answered 11/3, 2013 at 19:52 Comment(0)
B
12

You probably want to use the Dispatcher object. I suggest you take a look a this Shawn Wildermuth's article: Build More Responsive Apps With The Dispatcher (MSDN magazine October 2007).

Bolection answered 11/5, 2011 at 5:38 Comment(5)
This wasn't 100% the solution, but it started me in the right direction. This is ultimately what worked: canvas.Dispatcher.Invoke(emptyDelegate, DispatcherPriority.Render); where emptyDelegate is Action emptyDelegate = delegate { };Parole
Thanks, Simon, for the edit you made earlier today. I am reading the article now.Locklin
The link to "Build More Responsive Apps With the Dispatcher" no longer works.Enchain
It works, but you'll have to browse to year 2007 and click October. I didn't put the exact link (plus it's a CHM) on purpose to avoid future broken links.Bolection
@Parole - TIL Dispatcher.Invoke() has 17 overloads 😂Chrysotile
M
6

Without a good Minimal, Complete, and Verifiable code example to show clearly what you're doing, it's impossible to know for sure what the best answer here is. However, from your description it sounds as though the maze-generating algorithm is executing in the UI thread, blocking the UI from updating itself.

Just as in the case with Winforms, where people are tempting to call methods like Refresh() or Application.DoEvents(), the real problem here is that you're blocking the UI thread. The right way to fix that is, don't do that.

There are lots of alternatives and without a more detailed question there's no way to know what would be the best approach in your case. However, the two most commonly used and most likely to be appropriate techniques are to use BackgroundWorker, or Task.Run() in combination with the Progress<T> class. In either case, your algorithm runs in a different thread, passing updates to the UI thread periodically (e.g. every rectangle, every ten rectangles, whatever). The UI thread receives an update, adds the data to the visuals, and then goes back to waiting for the next update.

BackgroundWorker and Progress<T> both provide built-in mechanisms for automatically marshalling data back to the UI thread. The only caveat is that whichever of those classes you're using, the instance of that class needs to be created on the UI thread. Since they need to be set up before you start executing the asynchronous work, this is typically not a problem; it comes for free.

If you do it this way, you won't need any hacks such as the three different ones that have been suggested here so far (two of which don't seem likely to be applicable in the "I've blocked my UI thread, now what?" scenario anyway).

Mythical answered 23/6, 2016 at 17:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.