复杂UI上的批量更新

时间:2011-07-17 19:17:06

标签: .net wpf user-interface bulk updates

我有一个非常复杂的用户界面,其状态栏不断变化,有多种类型的状态讯息和用户界面,其中包含复杂的图表控件和加载的指示性地理地图。

现在这些小而复杂的区域的数据上下文具有同样复杂的ViewModel,如StatusBarVM,ChartingVM,GeoMapVM等......它们实现了INotifyPropertyChanged和ObservableCollections。

计算我的更新我看到我有大约5000个UI项目(标签,进度条,图表数据点,bgcolorsbrushes等),它们以每秒1000次数据项更新的速度变化。

在WPF UI上实现批量数据更新的最佳方法是什么?

WPF的绑定模型是否能够进行如此大规模的更新?如果是这样的话?因为我认为在我的情况下它不是最佳的。我正在使用bgworker(for progressbars)并使用DIspatcher BeginInvoke ...但重点是即使这样,当调度程序消息排队等待完成时,更新会挂起UI线程。

我无法实现虚拟化,因为状态是实时的,我必须在我面前的UI上看到它们。我甚至不能错过它们几秒钟(例如常数变化的卫星的地理数据)。

请帮我确定一个正确的工具或某种方法来实现复杂但高度响应的WPF UI。是Dispatcher.PushFrame()?

1 个答案:

答案 0 :(得分:4)

每秒有很多更新,您将在队列中“备份”更新消息,这就是您的后台工作程序更新被阻止的原因。

要解决此问题,您需要限制抛出的更新事件的数量。

我会使用这样的方法:

在我的ViewModel中,用对单个对象的调用替换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左右“释放”一次通知 - 仍然足够快,用户不会注意到任何差异,它看起来像实时更新,但速度足以检测(和删除)重复通知。