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

WPF Toolkit DataGrid прокручивает проблемы с производительностью - почему?

У меня проблема с производительностью (DataGrid) WPF Toolkit. Он содержит около 1.000 строк (всего восемь столбцов), а прокрутка очень медленная и медленная. Также начальная загрузка окна, содержащего DataGrid, занимает 5-10 секунд.

Я провел некоторое исследование (используя Google и StackOverflow), но не смог найти ничего, кроме совета по включению виртуализации пользовательского интерфейса. Но даже после того, как явным образом разрешаю эту прокрутку, она продолжает быть очень медленной.

My DataGrid привязан к ICollectionView/CollectionViewSource. Он определен в XAML как это (столбцы явно определены, а не сгенерированы автоматически):

    <tk:DataGrid x:Name="dataGrid" 
                 ItemsSource="{Binding Path=Bookings}" 
                 AutoGenerateColumns="False" 
                 Grid.Row="1" 
                 EnableRowVirtualization="True" 
                 EnableColumnVirtualization="True"
                 VirtualizingStackPanel.IsVirtualizing="True"
                 VirtualizingStackPanel.VirtualizationMode="Recycling">
            ... 
    </tk:DataGrid>

DataContext для всего окна установлен в экземпляр класса, содержащего ICollectionView, к которому привязан DataGrid.

Каждый блог или сообщение на форуме, которое я нашел, восхваляло производительность DataGrid, поэтому я совершенно очевидно делаю что-то серьезное. Поскольку я совершенно новый для WPF вообще и особенно для DataGrid, я не знаю, как это улучшить. Есть ли у кого-нибудь совет для меня? Каков ваш опыт работы с DataGrid? Что я делаю неправильно?

Изменить: просто выполните этот вопрос, чтобы установить ширину всех столбцов в значение "Авто". Это привело к тому, что не изменил производительность плохой прокрутки. Также я не использую DataGridTemplateColumns (только некоторые DataGridTextColumns и две DataGridComboBoxColumns).

Edit2: Я использовал Snoop для просмотра моего приложения. Я вижу, что виртуализация действительно работает (всего 19 строк, а не тысяча). Но каждая строка содержит 52 элемента, поэтому они содержат более тысячи элементов. Возможно, это проблема /

Спасибо большое!

4b9b3361

Ответ 1

Наконец-то создав время для создания моего приложения против обновленной версии WPF, проблема прокрутки кажется полностью утерянной. Поэтому, если кто-то все еще использует версию инструментария DataGrid, просто "обновляю" версию, включенную в структуру, и все должно быть хорошо.

Ответ 2

У DataGrid есть свойство Attached, ScrollViewer.CanContentScroll, которое управляет этим поведением. Чтобы получить плавную прокрутку, вам нужно установить значение False.

Ответ 3

Я использую .NET 4.0 и все еще получаю проблему с производительностью прокрутки. То, что я сделал - отключена виртуализация. Я установил EnableRowVirtualization в 'false' в DataGrid. Это значительно улучшило характеристики прокрутки.

Я бы предложил не предполагать, что все, что предлагается WPF, полезно во всех ситуациях.

Ответ 4

В каком контейнере живет ваш datagrid? Например, если вы поместите его в scrollviewer, то datagrid будет расти, чтобы отображать каждую строку, тем самым эффективно отключая виртуализацию (и scrollviewer будет казаться нормальным, пока это произойдет). Убедитесь, что размер набора данных ограничен.

Это действительно звучит как вещь виртализации, если этот совет не работает, запустите приложение через профилировщик, чтобы убедиться, что виртуализация происходит.

Изменить: Вот пример того, как использовать snoop (или моль, я думаю), чтобы быстро увидеть, работает ли виртуализация. http://blogs.msdn.com/jgoldb/archive/2008/03/25/quick-tips-to-improve-wpf-app-memory-footprint.aspx

Ответ 5

Вы можете попробовать добавить элементы по одному (или по строке) в datagrid и обновить поток пользовательского интерфейса после каждого добавления. Таким образом, пользователь видит, что загрузка происходит, и похоже, что приложение ничего не делает. См. здесь более подробное описание этого метода

Ответ 6

Что касается начальной загрузки, я обнаружил, что необходимо расширить публичный API, чтобы значительно улучшить большую загрузку столбцов - мы говорим минут до секунды. Тем не менее, у меня есть аналогичные проблемы со скоростью прокрутки, даже 500+ столбцов очень медленно прокручиваются.

Установка столбцов в моем производном datagrid:

var columns = new DataGridColumnCollection(true, dataGrid);
        for (int i = 0; i < pivotTable.DetailsColumnCount; i++)
        {
            if (!pivotTable.NullColumns.Contains(i))
            {
                columns.Add(new PivotDetailColumn(pivotTable, i));
            }
        }
        columns.ForceUpdate();

        dataGrid.Columns = columns;

        dataGrid.ItemsSource =
            Enumerable.Range(0, pivotTable.DetailsRowCount)
                .Where(i => !pivotTable.NullRows.Contains(i)) // Only non null rows
                .ToList();

Исправления для DataGridColumnCollection:

public class DataGridColumnCollection : ObservableCollection<DataGridColumn>
{
    private bool _DeferColumnChangeUpdates = false;

    public DataGridColumnCollection(bool deferColumnChangeUpdates, DataGrid dataGridOwner)
        : this(dataGridOwner)
    {
        _DeferColumnChangeUpdates = deferColumnChangeUpdates;
    }

    public DataGridColumnCollection(DataGrid dataGridOwner)
    {
        Debug.Assert(dataGridOwner != null, "We should have a valid DataGrid");

        DisplayIndexMap = new List<int>(5);
        _dataGridOwner = dataGridOwner;

        RealizedColumnsBlockListForNonVirtualizedRows = null;
        RealizedColumnsDisplayIndexBlockListForNonVirtualizedRows = null;
        RebuildRealizedColumnsBlockListForNonVirtualizedRows = true;

        RealizedColumnsBlockListForVirtualizedRows = null;
        RealizedColumnsDisplayIndexBlockListForVirtualizedRows = null;
        RebuildRealizedColumnsBlockListForVirtualizedRows = true;
    }

    #region Protected Overrides

    public void ForceUpdate()
    {
        if (DisplayIndexMapInitialized)
        {
            UpdateDisplayIndexForNewColumns(this, 0);
        }

        InvalidateHasVisibleStarColumns();
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
            if (!_DeferColumnChangeUpdates)
            {
                if (DisplayIndexMapInitialized)
                {
                    UpdateDisplayIndexForNewColumns(e.NewItems, e.NewStartingIndex);
                }

                InvalidateHasVisibleStarColumns();
            }
                break;

Ответ 7

Я обнаружил, что при установке ширины столбца на Auto (по умолчанию!) Может возникнуть значительная задержка вертикальной прокрутки, когда имеется много ячеек. Переключение на фиксированную ширину очень помогло в моем случае, хотя при наличии большого количества столбцов все еще наблюдается определенная задержка.

Вы можете установить CanUserResizeColumns="True" в сетке, если вы беспокоитесь, что пользователям не понравятся выбранные вами ширины.