2011-07-17 42 views
5

我有一個非常複雜的用戶界面,其中包含多種狀態消息和具有複雜圖表控件和指示性地理地圖加載的UI的不斷變化的狀態欄。複雜用戶界面上的批量更新

現在這些小而複雜的區域的數據上下文具有同樣複雜的ViewModel,如StatusBarVM,ChartingVM,GeoMapVM等......它們實現INotifyPropertyChanged和ObservableCollections。

計算我的更新我看到我有大約5000個UI項目(標籤,進度條,圖表數據點,bgcolorsbrushes等),它們以每秒1000個數據項更新的速度進行更改。

在WPF UI上實現批量數據更新的最佳方式是什麼?

WPF的綁定模型能夠進行如此巨大的更新嗎?如果是這樣如何?因爲我認爲它不是最適合我的情況。我使用bgworker(用於progressbar)以及使用DIspatcher BeginInvoke ...但問題是即使這樣,當調度程序消息正在排隊等待完成時,更新也會掛起UI線程。

我無法實現虛擬化,因爲這些狀態是實時的,我必須在用戶界面上看到它們,即使在幾秒鐘之內我也不會錯過它們(例如,不斷變化的衛星地理數據) 。

請幫我確定一個正確的工具或某種方式來實現複雜但高度響應的WPF UI。它是Dispatcher.PushFrame()嗎?

回答

4

由於每秒有很多更新,您將在隊列中獲得「備份」更新消息,這就是爲什麼您的後臺工作人員更新被阻止的原因。

要解決此問題,您需要限制正在拋出的更新事件的數量。

我會用這樣的方法:

在我的ViewModels,用一個單獨的對象的話,可以代表發送該對象的通知取代正常執行INotifyPropertyChanged的的。

private void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedNotifier.Notify(this, propertyName, propertyChanged); 
} 

其中propertyChanged是存儲此對象事件處理程序的成員變量。

Notify方法會是這個樣子:

public static void Notify(
    object sender, 
    string propertyName, 
    PropertyChangedEventHandler handlers) 
{ ... } 

內通知,不要馬上發送事件 - 只是存儲它需要發送的事實。

如果您多次收到相同對象/屬性的通知,請放棄額外的通知。如果您多次收到同一個對象但屬性不同的通知,請將該通知替換爲a single one for all properties

現在,使用UX線程計時器每50ms左右「發佈」通知 - 仍然足夠快,以至於用戶不會注意到任何區別,它看起來像是實時更新,但速度足以檢測(並刪除)重複通知。

+0

這看起來像一個很好的實現,雖然我必須要問的是基於緩衝區的UI更新(其他UI技術,如ASP.NET,WinForms等)跟你在這裏討論過的一樣嗎? –

+1

我不確定,術語「基於緩衝區的UI更新」並不是我認識到的。 – Bevan

+1

您應該考慮使用此框架批量更新:[Reactive Extensions](https://rx.codeplex.com/),隨時間查看零件緩衝區。 – Thomas