WPF DataGrid очень медленно отображает
Я попытался использовать как настроенный DataGrid, так и запасной в WPF. Я попытался заселить их вручную, а также с помощью привязок. В обоих случаях они медленны.
У меня есть scenerio, где пользователь нажимает кнопку и появляется DataGrid с соответствующими данными. В настоящее время я подтверждаю концептуальный режим и просто использую образцы данных. У меня есть DataSet с таблицей, в которой есть 10 строк.
Если я не прикрепляю какие-либо данные к DataGrid, когда я нажимаю кнопку, пустой DataGrid отображается в значительной степени мгновенно, пользователь не может воспринимать задержку. Как только я добавлю 10 строк данных, для 6 столбцов задержка составляет около 2 секунд, что очень заметно для пользователя.
Я даже попробовал заполнить пустые данные, просто чтобы получить пустую сетку, и она будет столь же медленной.
for (int i = 0; i < 10; i++)
_dataGrid.Items.Add("");
Я помещаю таймер для подсчета тиков, когда нажата кнопка, когда весь код выполняется для рисования DataGrid, и это около 20 миллисекунд, поэтому код выполняется очень быстро, но на экране есть большой лаг. Я попробовал GridView, и он очень быстро отображается на экране.
Я слышал различные отчеты о медленном графике DataGrid со сложными сценариями и использовании 1000 строк, но это так же просто, как и он, 6 столбцов на 10 строк, заполненных пустыми данными.
Для отображения только для чтения GridView является одинаково жизнеспособным вариантом для DataGrid?
Update
Вот создание моих столбцов.
DataGridTextColumn column = new DataGridTextColumn();
column.ColumnWidthChanged += new ColumnWidthChangedEventHandler(column_ColumnWidthChanged);
column.Header = entity.GetPropertyValue("ColumnLabel");
column.Binding = new Binding(entity.GetPropertyValue("Tag"));
column.Width = new DataGridLength(entity.GetPropertyDouble("DisplaySize"));
_dataGrid.Columns.Add(column);
Вот как я связываю DataSet с 10 строками в нем.
_dataGrid.ItemsSource = ds.Tables[0].DefaultView;
_dataGrid.DataContext = ds.Tables[0];
Не уверен, что я могу сделать по-другому.
Ответы
Ответ 1
У вас есть:
- Включено
VirtualizingStackPanel.VirtualizationMode
для сетки? если нет - попробуйте установить.
- Установить VirtualizingStackPanel.IsVirtualizing = "true" для DataGrid
- Завершена решетка контейнером StackPanel? Если да - попробуйте удалить.
- Завершена решетка внешним элементом управления ScrollViewer? Если да - попробуйте удалить.
Еще один момент,
вы могли бы связать целую коллекцию предметов сразу, а не добавлять каждый элемент в таблицу grid.Items?
Ответ 2
Общий совет для проблем с производительностью DataGrid
: у меня возникла проблема с DataGrid, в которой потребовалось буквально секунд для обновления после изменения размера окна, сортировки столбцов и т.д. и блокировки пользовательского интерфейса окна во время его создания ( 1000 строк, 5 столбцов).
Это привело к проблеме (ошибка?) с расчетами размера WPF. Я имел это в сетке с RowDefinition
Height="Auto"
, которая заставляла систему рендеринга попробовать и пересчитать размер DataGrid во время выполнения, измеряя размер каждого столбца и строки, предположительно, заполнив всю сетку ( как я понимаю). Он должен воспринимать это разумно каким-то образом, но в этом случае это не так.
Быстрая проверка, чтобы убедиться, что это связанная с этим проблема, заключается в том, чтобы установить свойства Height
и Width
DataGrid на фиксированный размер в течение всего теста и повторить попытку. Если ваша производительность восстановлена, среди этих опций может быть постоянное исправление:
- Измените размеры содержащихся элементов как относительные (*) или
фиксированные значения
- Установите
MaxHeight
и MaxWidth
DataGrid на фиксированное значение больше
чем он может нормально работать.
- Попробуйте использовать другой тип контейнера с другой стратегией изменения размера (
Grid
,
DockPanel
и т.д.)
Ответ 3
Блог, который я нашел в Google, дал мне своеобразное решение. Как сказал автор, я отключил GroupStyle, и проблема с производительностью была решена. Но мне нужна была группировка. Автор сказал
VirtualizingPanel.IsVirtualizingWhenGrouping
добавлен в .NET 4.5. Поэтому я установил его в true. Теперь рендеринг выполняется быстро с группировкой. Проблема в том, что... прокрутка является рывком. Не неприемлемо рывком, но заметно рывком. У меня была аналогичная проблема, когда я попытался создать TreeView с 2000+ расширенными узлами. Без виртуализации рендеринг был медленным, но прокрутка была гладкой. С виртуализацией рендеринг был быстрым, но прокрутка была отрывистой.
Почему мы не можем иметь оба...
Ответ 4
В моем случае у меня была проблема с DataGridCell ControlTemplate, которая замедляла процесс рендеринга.
Помните, что относительная скорость загрузки большого набора данных очень различна для использования TextBlock (это не выбираемый текст) или TextBox в режиме ReadOnly:
Время загрузки 59 секунд:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox IsReadOnly="True" Text="{Binding Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Время загрузки 21 секунда:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Время загрузки 16 секунд:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBlock Text="{Binding}"></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ответ 5
У меня есть Surface Pro 3, на котором мой datagrid, содержащий около 200 строк и 10 столбцов, был очень медленным при прокрутке, рывках и нерешительности.
Я думал, что это была сеть, но на самом деле графическая карта не могла идти в ногу с этим - дождаться ее - эффект теневой тени на сам файл данных, хотя фон элемента управления был установлен на сплошной цвет.
Я прокомментировал эффект, и он был в 4-5 раз быстрее.
Надеюсь, что это поможет.
Ответ 6
У меня такая же проблема с привязанной сеткой данных, и я замечаю, что при первой загрузке она работает быстро, но в секундах, а затем медленная. Поэтому, когда я добавляю код
DataGrid.ItemsSource = Nothing
, а затем TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure
он стал очень быстрым
Ответ 7
Для меня это было:
<Setter Property='ScrollViewer.CanContentScroll' Value='False' />
Я удалил это из стиля, и рендеринг стал быстрым.
Ответ 8
Ну немного добавив больше (я знаю его очень старую тему, но все же это помогает кому-то)...
Я пробовал
EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True"
для привязки DataGrid (AutoGenerateColumns="True"
) к DataTable.DefaultView() и никакого влияния на скорость, он все еще был ужасен для скорости, а также для навигации между строками. Затем я придумал решение установить фиксированную высоту и ширину DataGrid. Кроме того, я также установил
RowHeight="23"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Это заставляет мою страницу заполняться очень быстро... Вместо 2 минут, теперь она занимает едва 10-12 секунд.
Надеюсь, что это поможет кому-то.
Примечание. Я использую .Net 4.5