c# /WPF通过数据触发器提高了同时填充更新1000个控件的性能



所以在模型方面,我有一个100x100的Cell对象数组。这些对象只有一个属性State,这是一个bool值。Cell实现INotifyPropertyChanged。我还有一个CellCollection对象,它保存100x100数组,并具有修改该数组的方法。

在视图侧,我有一个包含10,000个矩形控件的画布,排列在100x100的网格中。100x100数组的每个元素都被设置为画布中相应矩形的DataContext。在XAML中为矩形控件定义了一个数据触发器,它绑定在矩形的DataContext的State属性上。如果State的值为True,则矩形的背景设置为黑色(通过Setter),如果它为False,则背景设置为白色。

现在我有一个DispatcherTimer,每隔100毫秒运行一次,调用CellCollection对象上的一个方法。该方法计算数组的状态,并更改其中一些元素的state属性的值。当State属性的值发生变化时,这些变化会如预期的那样反映在GUI中。

唯一的问题是,它非常慢。

所以dispatcher调用的CellCollection方法分为两部分:首先计算cell数组的新状态,并将结果存储在100x100 bool数组中。其次,它遍历Cell数组并根据bool数组中的值更新其元素的State属性。我打印了一些时间戳到控制台,似乎计算bool数组需要大约10毫秒,所以我不认为这是我的算法效率低下的问题,而是我推测缓慢是由于单元格几乎同时更新(触发属性更改事件,进而触发数据触发器改变相应矩形的填充值)。

我是c#和WPF的新手,所以我不完全确定如何使它更快。有人告诉我,可以使用Dispatcher来极大地提高性能,但我不确定如何这样做。我也知道BackgroundWorker类,但我不完全确定在这种情况下如何使用它。

最初我将Cell的State属性绑定到Rectangle的Fill属性,并使用ValueConverter将bool值转换为颜色。有人建议DataTriggers可能会更快,这就是我目前使用的,但我没有真正注意到任何性能改进。其他人还建议我应该使用RectangleGeometry和Path对象而不是Rectangle对象,因为它可能会提高图形性能,但我不确定这是否准确,并且没有成功实现这一点。

无论如何,我能做些什么来提高我的应用程序的性能?

首先,确保您只更改实际更改值的单元格。如果有些东西保持不变,不要设置属性背景字段,也不要发出NotifyChanged信号。

这很可能没有帮助。所以你需要另一种方法。您没有提到通过这个wpf元素的任何输入。所以我认为它们只是用来展示的。更新10K个元素,因为它更容易处理……更容易操作,但非常慢。您真正想要的是显示100 x 100单元格图片的单个元素。尝试先在代码中将该图片绘制成位图,然后通过使用Image控件并绑定到位图,使位图出现在屏幕上。当你绘制时,位图是旧的,一旦你在后台生成了位图,你可以设置这个新的位图。

你可以在后台线程中处理位图的绘制,但我的猜测是,这将是一种快速的方式,使意义

最新更新