问题
I've actually got 2 similar problems here with no luck finding anything on the web.
Problem 1: Using a BackgroundWorker, I am updating the UI with the % done, but I am using the UserState because I want to report fraction of a percent. The problem is, depending on the inputs, sometimes updates happen rarely (a percent every couple seconds) and other times very fast (triggering fractional % updates many times a second). In the latter case, I'm getting a stack overflow (no pun intended) issue. I'm guessing the ProgressChanged event is just getting called too much. This is for now prototype code and I'm updating a TextBlock directly in the progressChanged event and not using ViewModels, but I will later. Not sure if this might be the problem. Is there a way to allow this progress changed event to get called how often it needs to, but say something like: if (!mytextblock.IsRendering()) mytextblock.text = newPercent;
That way it updates just when it's done drawing the last number. If percents get skipped, that's ok.
Problem 2: This is a personal project where I'm taking a screen capture, changing it in some way, then showing the changed image within the wpf program, and repeat continuously. Is there a way to say: GrabScreen EditImage UpdateUI WaitForUIToRender // <------- how do I do this? Repeat
thank you
回答1:
public class TimedAction
{
public static void ExecuteWithDelay(Action action, TimeSpan delay)
{
var timer = new DispatcherTimer();
timer.Interval = delay;
timer.Tag = action;
timer.Tick += timer_Tick;
timer.Start();
}
static void timer_Tick(object sender, EventArgs e)
{
var timer = (DispatcherTimer)sender;
var action = (Action)timer.Tag;
action.Invoke();
timer.Stop();
}
public static void ExecuteAfterRendering(Action action)
{
ExecuteAfterFrames(action, 3);
}
public static void ExecuteAfterFrames(Action action, int frames)
{
var timedAction = new TimedAction();
timedAction._currentAction = action;
timedAction._framesToWait = frames;
}
private Action _currentAction;
private int _framesToWait;
private int _currentFrame = 0;
private TimedAction()
{
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
private void Dispose()
{
CompositionTarget.Rendering -= CompositionTarget_Rendering;
}
void CompositionTarget_Rendering(object sender, EventArgs e)
{
_currentFrame++;
if (_currentFrame == _framesToWait)
{
_currentAction.Invoke();
Dispose();
}
}
}
来源:https://stackoverflow.com/questions/22386325/waiting-for-ui-re-rendering-to-complete