Dot-Net

確保在 MVVM WPF 應用程序的 UI 執行緒上呼叫 OnPropertyChanged()

  • February 26, 2009

在我使用 MVVM 模式編寫的 WPF 應用程序中,我有一個後台程序來做這件事,但需要從它獲取狀態更新到 UI。

我正在使用 MVVM 模式,因此我的 ViewModel 幾乎不知道將模型呈現給使用者的視圖 (UI)。

假設我的 ViewModel 中有以下方法:

public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
   this.Messages.Add(e.Message);
   OnPropertyChanged("Messages");
}

在我看來,我有一個 ListBox 綁定到List<string>ViewModel 的 Messages 屬性 (a)。 通過呼叫 aOnPropertyChanged來完成介面的作用。INotifyPropertyChanged``PropertyChangedEventHandler

我需要確保OnPropertyChanged在 UI 執行緒上呼叫它 - 我該怎麼做?我嘗試了以下方法:

public Dispatcher Dispatcher { get; set; }
public MyViewModel()
{ 
   this.Dispatcher = Dispatcher.CurrentDispatcher;
}

然後將以下內容添加到OnPropertyChanged方法中:

if (this.Dispatcher != Dispatcher.CurrentDispatcher)
{
   this.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(delegate
   {
       OnPropertyChanged(propertyName);
   }));
   return;
}

但這沒有用。有任何想法嗎?

WPF 自動將屬性更改編組到 UI 執行緒。但是,它不會編組集合更改,因此我懷疑您添加消息會導致失敗。

您可以自己手動編組添加(請參見下面的範例),或者使用類似我不久前在部落格中寫過的這種技術。

手動編組:

public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
   Dispatcher.Invoke(new Action<string>(AddMessage), e.Message);
   OnPropertyChanged("Messages");
}

private void AddMessage(string message)
{
   Dispatcher.VerifyAccess();
   Messages.Add(message);
}

引用自:https://stackoverflow.com/questions/590590