Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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