Как уже говорили другие, проблема в том, что вы блокируете поток пользовательского интерфейса.
Вместо того, чтобы использовать предложения с Application.DoEvents
, я бы предложил использовать DispatcherTimer
чтобы запланировать обновление.Пример кода:
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += delegate
{
label.Content = counter.ToString();
counter++;
if (counter == 500)
{
timer.Stop();
}
};
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Start();
(я не уверен, работает ли Application.DoEvents
даже в WPF, и вообще все равно считается плохой практикой. Если это работает , я сомневаюсь, чтоон гарантированно будет работать в будущих версиях. Смешивание двух интерфейсов в одном приложении только для меня звучит как очень плохая идея.)
Вы могли бы использовать Timer
(либо System.Threading.Timer
, либо System.Timers.Timer
), но в обоих случаях вам все равно придется вернуться обратно к ветке диспетчера.DispatcherTimer
делает это проще - событие Tick
всегда вызывается в потоке Dispatcher
.
EDIT: Если вы действительно хотите получить эквивалент DoEvents
, вот кодкоторый я проверял, работает, и основан на документах MSDN для Dispatcher.PushFrame
, объясняющих, как сделать эквивалент Application.DoEvents
, но из 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();
}
}
Я все ещехотя я бы не рекомендовал этого - WPF (например, Windows Forms) разработан на основе метода работы, основанного на событиях.