WPF元素事件处理程序中的UI更新

WPF元素事件处理程序中的UI更新,wpf,multithreading,user-interface,event-handling,Wpf,Multithreading,User Interface,Event Handling,WPF中的UI更新有问题 我有这样的代码: private void ButtonClick_EventHandler(object sender, RoutedEventArgs e) { Label.Visibility = Visibility.Visible; TextBox.Text = "Processing..."; LongTimeMethod(); //some long operation } 问题是

WPF中的UI更新有问题

我有这样的代码:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        LongTimeMethod(); //some long operation
    }
问题是,在LongTimeMethod结束(即事件处理程序结束)之前,Label.Visibility和TextBox.Text不会更改

到目前为止,我是这样解决的:

    private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
    {
        Label.Visibility = Visibility.Visible;
        TextBox.Text = "Processing...";

        Dispatcher.BeginInvoke(new Action(LongTimeMethod), 
            DispatcherPriority.Background);
    }

有没有其他不使用dispatcher调用的解决方案?调用此.UpdateLayout()没有帮助。

可见性和文本是由dispatcher更新的依赖属性。您的解决方案绝对正确,但我的建议是异步执行


另一方面,您可以在WPF()中模拟Application.DoEvents。

使用
Dispatcher.BeginInvoke
您仍然在使用
LongTimeMethod()的UI线程。如果这不是必需的(即它正在进行某种后台处理),我建议使用TPL在后台线程上运行它:

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e)
{
    Label.Visibility = Visibility.Visible;
    TextBox.Text = "Processing...";

    Task.Factory.StartNew(() => LongTimeMethod())
        .ContinueWith(t =>
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                TextBox.Text = "Done!";
            });
        });

}

使用此方法,长时间运行的方法在后台线程上处理(因此UI线程可以自由地继续渲染,应用程序不会冻结),并且您可以执行任何更改UI的操作(例如更新文本框文本)后台任务完成后,在UI
Dispatcher
上有一个原因Application.DoEvents没有被带入WPF!如果你想释放UI线程,你应该释放UI线程,而不是通过处理任何挂起的消息来伪造它。我们坚持并行性,我刚刚建议了另一种解决方案。在这种情况下,可以,该方法在UI线程中运行。我只是想避免使用dispatchers、threads等@brain_pusher,如果UI线程正在执行长时间运行的操作,那么它将无法更新您设置的UI属性。通过使用Dispatcher.BeginInvoke
您可以说“在UI线程上执行此操作,但不要立即执行;完成当前任务后再做。这就是为什么您会看到更新的UI