As others have said, the problem is that you're blocking the UI thread.
Rather than use the suggestions with Application.DoEvents
, I would suggest that you use a DispatcherTimer
to schedule the update. Sample code:
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += delegate
{
label.Content = counter.ToString();
counter++;
if (counter == 500)
{
timer.Stop();
}
};
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Start();
(I'm not sure whether Application.DoEvents
even works in WPF, and it's generally regarded as bad practice anyway. If it does work, I doubt that it's guaranteed to work in future versions. Mixing the two UIs in the same application just for the sake of this sounds like a really bad idea to me.)
You could use a Timer
(either System.Threading.Timer
or System.Timers.Timer
) but in both cases you'd then need to marshal back to the dispatcher thread anyway. DispatcherTimer
makes this simpler - the Tick
event is always fired within the Dispatcher
thread anyway.
EDIT: If you really want an equivalent of DoEvents
, here's code which I've verified does work, and is based on the MSDN docs for Dispatcher.PushFrame
explaining how to do the equivalent of Application.DoEvents
but from WPF:
public void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrames), frame);
Dispatcher.PushFrame(frame);
}
public object ExitFrames(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 500; i++)
{
label.Content = i.ToString();
DoEvents();
}
}
I still wouldn't recommend this though - WPF (like Windows Forms) is designed on an event-driven way of working.