在我的.NET 3.5
WPF
应用中,我有一个WPF
DataGrid
,其中将填充500列和50行。
滚动时,或者当我DataGrid.Items.Refresh()
或选择行时,应用程序的性能非常差。
实际上应用程序将花费大约20秒来更新布局。 Layout_Updated()
事件将在20秒后触发。
如果我将列减少到50或更少,App将会非常敏感。根据我的发现,性能与列数直接相关。
如何改善DataGrid
效果?
答案 0 :(得分:67)
您可以使用一些选项来帮助您使用 DataGrid 对象
EnableColumnVirtualization = true
EnableRowVirtualization = true
这两个是我认为可能有帮助的主要因素。接下来尝试使您的绑定异步
ItemsSource="{Binding MyStuff, IsAsync=True}"
最后,我听说设置最大高度和宽度可以帮助,即使它超过最大屏幕尺寸,但我自己没有发现差异(声称与自动尺寸测量有关)
MaxWidth="2560"
MaxHeight="1600"
也永远不会将DataGrid
放在ScrollViewer
中,因为您将基本上失去虚拟化。如果这有帮助,请告诉我!
答案 1 :(得分:4)
检查您是否将ScrollViewer.CanContentScroll
设置为False
。
将此属性设置为false会以某种方式禁用虚拟化,这会降低数据网格的性能。有关更多说明,请参阅此CanContentScroll
答案 2 :(得分:1)
设置{
"url": "https://example_site.in/new/blogs",
"server": {
"port": 2368,
"host": "127.0.0.1"
},
"database": {
"client": "mysql",
"connection": {
"host": "localhost",
"user": "admin",
"password": "<DB Pass>",
"database": "<DB name>"
}
},
"mail": {
"transport": "SMTP",
"options": {
"host": "smtp.zoho.com",
"port": 587,
"secureConnection": false,
"auth": {
"user": "<email>",
"pass": "<pass>"
}
}
},
"logging": {
"transports": [
"file",
"stdout"
]
},
"process": "systemd",
"paths": {
"contentPath": "/var/www/html/example_blogs/content"
}
}
值,这将带来很大的不同。
我知道这是一个非常老的问题,但是我碰到了这个问题,这是我最大的不同。我的默认身高是25。
答案 3 :(得分:0)
也许试试这个而不是一次加载所有50行
http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization
答案 4 :(得分:0)
这个答案 (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 instad 之前的 4 GB。
为了测试,我禁用了所有 IValueConverter
并实现了我直接绑定的属性。如果没有转换器,DataGrid 会立即刷新。所以我离开了。