在我的.NET 3.5
WPF
应用程序中,我有一个WPF
DataGrid
将填充 500 列和 50 行的内容。应用程序的性能在滚动时非常差,或者当我这样做时DataGrid.Items.Refresh()
或在选择行时。
实际上 App 大约需要 20 秒来更新布局。Layout_Updated()
事件将在 20 秒后触发。
如果我将列减少到 50 或更少,应用程序将非常敏感。根据我的发现,性能与列数直接相关。
如何提高DataGrid
性能?
在我的.NET 3.5
WPF
应用程序中,我有一个WPF
DataGrid
将填充 500 列和 50 行的内容。应用程序的性能在滚动时非常差,或者当我这样做时DataGrid.Items.Refresh()
或在选择行时。
实际上 App 大约需要 20 秒来更新布局。Layout_Updated()
事件将在 20 秒后触发。
如果我将列减少到 50 或更少,应用程序将非常敏感。根据我的发现,性能与列数直接相关。
如何提高DataGrid
性能?
您可以打开几个选项来帮助您处理DataGrid对象
EnableColumnVirtualization = true
EnableRowVirtualization = true
这两个是我认为可能有帮助的主要内容。接下来尝试使您的绑定异步
ItemsSource="{Binding MyStuff, IsAsync=True}"
最后,我听说设置最大高度和宽度会有所帮助,即使它高于最大屏幕尺寸,但我自己并没有注意到差异(声称与自动尺寸测量有关)
MaxWidth="2560"
MaxHeight="1600"
也永远不要把 a 放在 aDataGrid
中ScrollViewer
,因为你基本上会失去虚拟化。让我知道这是否有帮助!
检查您是否ScrollViewer.CanContentScroll
设置了属性False
。将此属性设置为 false 会以某种方式禁用虚拟化,从而降低数据网格的性能。有关更多说明,请参阅此CanContentScroll
设置DataGrid.RowHeight
值,这将产生巨大的影响。
我知道这是一个非常古老的问题,但我只是遇到了它,这是我最大的不同。我的默认高度是 25。
这个答案(Set ScrollViewer.CanContentScroll to True)让我走上了正轨。但我需要将其设置为false
. 为了将它设置为true
当我进行刷新时,我编写了这两种方法。
internal static void DataGridRefreshItems(DataGrid dataGridToRefresh)
{
/// Get the scrollViewer from the datagrid
ScrollViewer scrollViewer = WpfToolsGeneral.FindVisualChildren<ScrollViewer>(dataGridToRefresh).ElementAt(0);
bool savedContentScrollState = scrollViewer.CanContentScroll;
scrollViewer.CanContentScroll = true;
dataGridToRefresh.Items.Refresh();
/// Was set to false, restore it
if (!savedContentScrollState)
{
/// This method finishes even when the update of the DataGrid is not
/// finished. Therefore we use this call to perform the restore of
/// the setting after the UI work has finished.
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => SetScrollViewerCanContentScrollFalse(scrollViewer)), DispatcherPriority.ContextIdle, null);
}
}
private static void SetScrollViewerCanContentScrollFalse(ScrollViewer scrollViewer)
{
scrollViewer.CanContentScroll = false;
}
这是我用来获取 VisualChildren 的方法:
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
在此之后,我刷新 50.000 个新项目仅持续 10 秒,与 2 分钟不同,并且仅消耗 2 MB 的 RAM 而不是之前的 4 GB。
为了测试,我禁用了我IValueConverter
直接绑定的所有和实现的属性。如果没有转换器,DataGrid 会立即刷新。所以我离开了它。
也许试试这个而不是一次加载所有 50 行
http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization