WPF DataGrid очень медленно рендерится - PullRequest
32 голосов
/ 13 июля 2011

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

У меня есть сценарий, где пользователь нажимает кнопку, и появляется DataGrid с соответствующими данными. В настоящее время я нахожусь в режиме проверки концепции и просто использую примеры данных. У меня есть DataSet с таблицей, в которой 10 строк.

Если я не прикрепляю данные к DataGrid, когда нажимаю кнопку, пустой DataGrid отображается практически мгновенно, пользователь не может воспринять задержку. Как только я добавляю 10 строк данных, для 6 столбцов задержка составляет около 2 секунд, что очень заметно для пользователя.

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

for (int i = 0; i < 10; i++)
    _dataGrid.Items.Add("");

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

Я слышал различные сообщения о медленном рисовании DataGrid со сложными сценариями и использовании тысяч строк, но это так просто, как получается, 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];

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

Ответы [ 9 ]

32 голосов
/ 13 июля 2011

Есть ли у вас:

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

Еще один момент, Вы могли бы связать всю коллекцию предметов сразу, вместо того, чтобы добавлять каждый элемент в сетку. Коллекция предметов?

24 голосов
/ 28 декабря 2011

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

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

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

  • Изменить размеры содержащихся элементов на относительные (*) или фиксированные значения
  • Установите MaxHeight и MaxWidth DataGrid на фиксированное значение больше чем он мог бы получить при обычном использовании
  • Попробуйте другой тип контейнера с другой стратегией изменения размера (Grid, DockPanel и т. Д.)
12 голосов
/ 28 февраля 2015

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

VirtualizingPanel.IsVirtualizingWhenGrouping

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

Почему мы не можем иметь оба ...

10 голосов
/ 28 января 2014

В моем случае у меня была проблема с 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>
4 голосов
/ 05 октября 2017

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

Я пытался

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

1 голос
/ 28 февраля 2019

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

<DataGrid
   EnableRowVirtualization="True"
   EnableColumnVirtualization="True">
1 голос
/ 16 апреля 2015

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

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

1 голос
/ 24 сентября 2014

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

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

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

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

0 голосов
/ 03 августа 2016

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...