2011-06-14 95 views
7

WPF中的UI更新存在问题。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); 
    } 

有没有使用调度调用任何其他解决方案?调用this.UpdateLayout()不起作用。

回答

1

可见性和文本是由调度程序更新的依赖项属性。你的解决方案绝对有效,但我的建议是异步执行。

另一方面,您可能会模拟WPF中的Application.DoEvents(see the article)。

+0

Application.DoEvents没有带入WPF!如果你想释放UI线程,你应该*释放UI线程*,而不是通过处理任何未决的消息来伪造它。 – 2011-06-14 16:30:45

+0

我们坚持并行化,我刚刚提出了一种替代解决方案。 – 2011-06-14 16:34:52

4

With Dispatcher.BeginInvoke您仍在使用UI线程为LongTimeMethod()。如果这不是必需的(即它是做某种类型的后台处理),我会建议使用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 Dispatcher上做任何改变UI的任何操作(例如更新文本框文本)

+0

在这种情况下,它可以,该方法在UI线程中运行。我只是想避免使用调度程序,线程等 – 2011-06-15 08:24:26

+2

@brain_pusher,如果UI线程正在执行长时间运行的操作,那么它将无法更新您设置的UI属性。通过使用'Dispatcher.BeginInvoke',你说'在UI线程上做这件事,但是现在不要做* *;当你完成你目前的任务时做到这一点'。这就是为什么你看到更新的UI – 2011-06-15 09:07:45

+0

'new Thread()。Start()'有什么区别? – Alex78191 2017-06-10 17:05:07

相关问题