WPF DataGrid очень медленно обрабатывает

Я пробовал использовать как настроенный DataGrid, так и стандартный в WPF. Я пробовал заполнять их вручную, а также через привязки. В обоих случаях они медленные.

У меня есть сценарий, в котором пользователь нажимает кнопку, и появляется 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?


Обновлять

Вот создание моих колонок.

                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];

Не уверен, что могу сделать по-другому.


person David Gunther    schedule 13.07.2011    source источник
comment
Я пробовал приложение на другой системе, и оно тоже было медленным. Проблема в том, что на некоторых представлениях есть несколько DataGrid, поэтому задержка просто увеличивается для каждой дополнительной DataGrid.   -  person David Gunther    schedule 13.07.2011
comment
Я использую стандартную сетку данных wpf с динамическими столбцами и более чем 10000 строк, и у меня нет проблем с этим. какой у вас источник товаров? datatable или некоторая коллекция? надеюсь, вы не добавляли элементы в foreach, как вы публикуете ??   -  person blindmeis    schedule 13.07.2011
comment
Я попробовал цикл for, как в сообщении, просто чтобы посмотреть, будет ли это иметь значение, я не был уверен, что проблема связана с привязкой. В действительности у меня есть DataSet, который я привязываю. Я обновлю пост.   -  person David Gunther    schedule 13.07.2011
comment
Очень тесно связано: stackoverflow.com/questions/697701/wpf-datagrid -перформанс /   -  person Robert Harvey    schedule 28.12.2011


Ответы (11)


У тебя есть:

  • Включено VirtualizingStackPanel.VirtualizationMode для сети? если нет - попробуй поставить.
  • Установите VirtualizingStackPanel.IsVirtualizing = "true" для DataGrid.
  • Обернули сетку контейнером StackPanel? Если да - попробуйте удалить.
  • Обернули сетку внешним элементом управления ScrollViewer? Если да - попробуйте удалить.

Еще один момент: можно ли связать сразу всю коллекцию элементов вместо добавления каждого элемента в коллекцию grid.Items?

person sll    schedule 13.07.2011
comment
Пытался вставить свой XAML, но ничего не вышло, я попробую обновить свой исходный вопрос. DataGrid содержится в DockPanel. Нет ScrollViewer, и я не ссылаюсь на VirtualizingStackPanel.VirtualizationMode. - person David Gunther; 13.07.2011
comment
Попробуйте установить для VirtualizingStackPanel.VirtualizationMode значение Recycling, например: ‹Grid VirtualizingStackPanel.VirtualizationMode = Recycling ... /› - person sll; 13.07.2011
comment
Благодарю за предложение, но оно, похоже, не помогло. - person David Gunther; 13.07.2011
comment
Неужто вы пытались добавить это свойство в элемент управления DataGrid, а не в Grid? Также попробуйте установить VirtualizingStackPanel.IsVirtualizing = true для DataGrid - person sll; 14.07.2011
comment
Да, я пробовал это в DataGrid, также добавил IsVirtualizing, и это действительно замедлило его работу. Я действительно озадачен. Код выполняется очень быстро, просто обновление происходит медленно. - person David Gunther; 14.07.2011
comment
Спасибо человеку за пост, я не думал, что вставка datagrid в панель стека может так сильно повлиять на скорость рендеринга. В моем случае разница в стековой панели и снаружи была почти в 100 раз. - person Vahagn Nahapetyan; 18.03.2016
comment
Ничего из этого не работает. DataGrid в WPF намного хуже сетки WinForms по производительности, ее практически невозможно использовать. - person Hrvoje Batrnek; 16.10.2020

Общий совет по DataGrid проблемам с производительностью: у меня была проблема с DataGrid, в которой требовалось буквально несколько секунд для обновления после изменения размера окна, сортировки столбцов и т. Д. И заблокировал пользовательский интерфейс окна во время этого (1000 строк, 5 столбцов ).

Это привело к проблеме (ошибке?) С расчетами размеров WPF. У меня он был в сетке с RowDefinition Height="Auto", из-за чего система рендеринга пыталась пересчитать размер DataGrid во время выполнения, измеряя размер каждого столбца и строки, предположительно, заполняя всю сетку (насколько я понимаю ). Предполагается, что как-то разумно с этим справится, но в данном случае этого не произошло.

Быстрая проверка, чтобы увидеть, связана ли это с проблемой, состоит в том, чтобы установить для свойств Height и Width DataGrid фиксированный размер на время теста и повторить попытку. Если ваша производительность восстановлена, среди следующих вариантов может быть постоянное исправление:

  • Измените размеры содержащихся элементов на относительные (*) или фиксированные значения
  • Установите MaxHeight и MaxWidth в DataGrid на фиксированное значение, большее, чем оно могло бы быть при нормальном использовании.
  • Попробуйте другой тип контейнера с другой стратегией изменения размера (Grid, DockPanel и т. Д.)
person TripleAntigen    schedule 28.12.2011
comment
У меня была такая же проблема с DataGrid, содержащимся в звездообразной строке макета Grid. Предлагаемая установка MaxHeight работает как шарм. - person EagleBeak; 11.03.2014

Блог, который я нашел в Google, дал мне своего рода решение. Как сказал автор, я отключил GroupStyle, и проблема со скоростью рендеринга была решена. Но мне нужна была группировка. Автор сказал

VirtualizingPanel.IsVirtualizingWhenGrouping

добавлен в .NET 4.5. Итак, я установил его в значение true. Теперь рендеринг выполняется быстро с группировкой. Проблема в том, что ... прокрутка дергается. Не неприемлемо рывками, но заметно рывками. У меня была аналогичная проблема, когда я пытался создать TreeView с расширенными узлами 2000+. Без виртуализации рендеринг был медленным, но прокрутка была плавной. С виртуализацией рендеринг был быстрым, но прокрутка была прерывистой.

Почему у нас не может быть и того, и другого ...

person Damn Vegetables    schedule 28.02.2015
comment
Эта единственная строка решила мою проблему - большое спасибо! Я возился с асинхронной задачей, которую я использую для загрузки данных, когда наконец понял, что реальная проблема была в рендеринге. Добавлен VirtualizingPanel.IsVirtualizingWhenGrouping="True", и население моей DataGrid теперь уменьшилось с 10 до менее секунды. - person M463; 09.06.2016
comment
Этот тоже у меня сработал! Спустился с 10-30 секунд до менее 1. - person Will Wainwright; 28.10.2016
comment
Что делать, если группировка не используется? - person AndrewRalon; 19.07.2019

В моем случае у меня была проблема с DataGridCell ControlTemplate, которая замедлила рендеринг.

Имейте в виду, что относительная скорость загрузки для больших наборов данных сильно различается при использовании TextBlock (не выбираемого текста) или TextBox в режиме только для чтения:

Время загрузки 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>
person Evalds Urtans    schedule 28.01.2014

Ну, немного добавлю еще (я знаю его очень старую тему, но все же это кому-то помогает) ...

Я пытался

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

person Nirav Raval    schedule 05.10.2017

У меня были большие проблемы с 1000 строками, 5 столбцами, где время рендеринга занимало 7-10 секунд, но решение было найдено на https://www.elegant-software.net/2014/05/performance-of-the-wpf-datagrid.html сделал сетку загружается мгновенно!

<DataGrid
   EnableRowVirtualization="True"
   EnableColumnVirtualization="True">
person Nick    schedule 28.02.2019
comment
В качестве быстрого обновления по этому поводу - в моем сценарии у меня был флажок в конце каждой строки, чтобы пользователи могли выбирать, какие строки им нужны, и после завершения они отправляли выбранные, но я обнаружил, что виртуализация строк была включена из-за его природа заключается в визуализации только того, что отображается на экране, он не учитывает выбранные строки, которые не были видны на экране, что привело к нескольким проблемам. Чтобы бороться с этим, я добавлял / удалял выбранные идентификаторы в переменную hashset всякий раз, когда выбиралась строка, и отслеживал их таким образом. - person Nick; 18.03.2019

Для меня это было:

<Setter Property='ScrollViewer.CanContentScroll' Value='False' />

Я удалил это из стиля, и рендеринг стал быстрым.

person waxingsatirical    schedule 03.08.2016
comment
Чтобы уточнить, установите ScrollViewer.CanContentScroll на true, поскольку значение false отключит виртуализацию. - person Slate; 04.12.2017
comment
С CanContentScroll на false у меня было время загрузки 20 секунд ... при true время загрузки мгновенное. Но плавной прокрутки больше нет. - person Blechdose; 09.08.2019

У меня есть Surface Pro 3, на котором моя сетка данных с примерно 200 строками и 10 столбцами очень медленно прокручивалась, рывками и неуверенно.

Я думал, что это сеть, но на самом деле графическая карта не могла справиться - подождите - эффект тени на самом сетке данных, даже если фон элемента управления был установлен на сплошной цвет.

Закомментировал эффект, он был в 4-5 раз быстрее.

Надеюсь это поможет.

person user3515346    schedule 24.09.2014

У меня такая же проблема с привязанной сеткой данных, и я замечаю, что при первой загрузке она выполняется быстро, а затем - медленно. Итак, когда я добавляю код

DataGrid.ItemsSource = Nothing а потом TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure стало очень БЫСТРО

person SLAVICA    schedule 16.04.2015
comment
извините, можно мне узнать подробности? - person Po-Sen Huang; 04.05.2018
comment
Требуются дополнительные сведения, поскольку вы можете сказать, что, похоже, существует много проблем с производительностью с сеткой данных. - person bjhuffine; 04.09.2019

Моя проблема заключалась в том, что в моем DataGrid было установлено ScrollViewer.CanContentScroll="False". Это полностью отключает виртуализацию для DataGrid. Более подробную информацию об этом можно найти здесь:

https://stackoverflow.com/a/3724695/4383302

person Sakarias Stenbäck    schedule 26.10.2020

Если у вас есть определение строки вроде belove:

 <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="*"/>
    </Grid.RowDefinitions>

Будьте осторожны! Например, если ваш Datagrid находится в одной из этих строк, его размер будет изменяться для каждой строки снова и снова. Если у вас 1000 строк, он будет увеличен в 1000 раз по сравнению с размером Datagrid!

Позвольте нам сказать, что ваш Datagrid находится в 3rd RowDefinition, тогда я предлагаю вам изменить код таким образом.

     <Grid.RowDefinitions>
        <RowDefinition x:Name="topRow" Height="*"/>
        <RowDefinition x:Name="mainRow" Height="*"/>
        <RowDefinition x:Name="dataGridRow" Height="400"/>
    </Grid.RowDefinitions>

Конечно, вы также можете изменить 400, как хотите.

person Doğuhan Yangöz    schedule 16.04.2021