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;
}
}
}
}
6条答案
按热度按时间6mw9ycah1#
您可以打开一些选项来帮助您处理DataGrid对象
这两个是我认为可能有帮助的主要因素。接下来尝试使绑定异步化
最后,我听说设置最大高度和宽度可以帮助,即使它高于最大屏幕尺寸,但我自己没有注意到差异(声称与自动尺寸测量有关)
另外,永远不要将
DataGrid
放在ScrollViewer
中,因为这样会失去虚拟化。让我知道如果这有帮助!8ljdwjyq2#
检查是否设置了
ScrollViewer.CanContentScroll
属性False
。将此属性设置为false将禁用虚拟化,这将降低数据网格的性能。有关详细说明,请参阅此CanContentScrollajsxfq5m3#
设置
DataGrid.RowHeight
值,这将产生巨大的差异。我知道这是一个很老的问题,但我只是偶然发现了它,这是我最大的不同。我的默认身高是25。
pw9qyyiw4#
第一步:从2分钟到10秒
这个答案(Set ScrollViewer.CanContentScroll to True)让我走上了正确的道路。但我需要将其设置为
false
。为了在刷新时将其设置为true
,我编写了以下两个方法。这是我用来获取VisualChildren的方法:
在此之后,我刷新50.000个新项目只持续10秒,不像2分钟,只消耗2 MB的RAM instad的4 GB之前。
第二步:从10秒到0.5秒
为了测试,我禁用了所有的
IValueConverter
,并实现了我直接绑定的属性。如果没有转换器,DataGrid会立即刷新。所以我把它留下了。g52tjvyc5#
也许可以尝试这样做,而不是一次加载所有50行
http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization
quhf5bfb6#
我发现一个折衷加载和滚动性能的最佳解决方案是为所有列的Binding设置
IsAsync=True
,而不是DataGrid ItemsSource Binding。示例:顺便说一下,当DataGrid上的虚拟化关闭时,这个解决方案工作得更好。但是,即使虚拟化打开,仍然值得一试。此外,当应用于显示图像等内容的DataGridTemplateColumn时,此解决方案非常有效。