我有一个WPF& C#app包含一个大型DataGrid,大约35个cols x 50行,用于监视一堆频繁变化的值。问题是,当整个网格可见时,刷新它会挂起用户界面几乎一秒钟。我每隔两秒就明确刷新一次,这对我正在做的事情来说很好,但是让其余的UI挂起是一件非常痛苦的事。
好的,所以我决定在一个单独的线程中使用单独的Dispatcher在单独的窗口中运行UI的其余部分。我写了一个玩具窗口,其中只包含一个textBlock,其递增计数使用DispatcherTimer每秒更新10次。但是,不是计数顺利递增,而是在网格刷新时暂停,然后恢复显示,其计数比暂停时高出约10倍,因此计时器事件正在处理中。我只是没有看到刷新。
WPF是否只在一个线程中绘制所有元素?有什么方法吗?
这是我的第二个窗口创建代码:
private void Window_Loaded( object sender, RoutedEventArgs e )
{
ThreadStart ts = new ThreadStart( RunSpareThread );
m_spare_thread = new Thread( ts );
m_spare_thread.IsBackground = true;
m_spare_thread.Priority = ThreadPriority.Highest;
m_spare_thread.SetApartmentState( ApartmentState.STA );
m_spare_thread.Start();
Dispatcher.Thread.Priority = ThreadPriority.Lowest;
}
void RunSpareThread()
{
m_spare_window = new SpareWindow();
m_spare_window.Show();
Dispatcher.Run();
}
仅供参考我尝试以几种不同的方式实现网格 - 作为ListView,作为覆盖OnRender的Canvas并绘制一大堆GlyphRunDrawings - WPF在绘制这些内容时非常缓慢。
答案 0 :(得分:3)
不幸的是,是的。也就是说,你可以做很多事情来提高你的ui的响应能力。其中一个主要方面是确保在UI线程中完成的工作量最少。这意味着在单独的上下文中完成所有数据库读取等操作。您还应该了解网格如何显示您的值 - 是否虚拟化?然后还有你是如何数据绑定的,绑定源应该允许你只在所有的更改完成后更新绑定。
答案 1 :(得分:1)
如果正确使用WPF,WPF会非常快。
一些提示:
MVVM
的ViewModel)。确保它实现了INotifyPropertyChanged
接口。将此类模型的集合绑定到DataGrid
; Dispatcher
(至少明确地); ListView
代替DataGrid
;