2011-06-14 98 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

相關問題