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

Производительность WPF Datagrid

Я работаю с сеткой данных WPF Toolkit, и в настоящий момент она прокручивается очень медленно. В сетке 84 столбца и 805 строк. (Включая 3 фиксированных столбца и заголовок фиксирован.) Прокрутка как по горизонтали, так и по вертикали чрезвычайно медленная. Виртуализация включена, и я включил виртуализацию столбцов и виртуализацию строк явно в xaml. Есть ли что-то, что можно было бы наблюдать за тем, что может реально повлиять на производительность, например, методы привязки или то, что xaml находится в каждом шаблоне celltemplate?

Следует отметить, что я динамически добавляю столбцы в создание datagrid. Может ли это что-то сделать? (Я также динамически создаю celltemplate в то же время, чтобы мои привязки были установлены правильно.)

Ниже приведен код шаблона для большинства генерируемых ячеек. В основном для столбцов, которые мне нужно динамически добавлять (это большинство из них), я просматриваю список и добавляю столбцы с помощью метода AddColumn, а также динамически строю шаблон, чтобы операторы привязки правильно индексировали нужный элемент в коллекции для этой колонки. Шаблон не слишком сложный, всего два блока TextBlocks, но я привязываю к ним по четыре разных свойства. Похоже, я смог выжать немного больше производительности, изменив привязки к OneWay:

 private void AddColumn(string s, int index)
    {
        DataGridTemplateColumn column = new DataGridTemplateColumn();
        column.Header = s;
        //Set template for inner cell two rectangles
        column.CellTemplate = CreateFactViewModelTemplate(index);
        //Set Style for header, ie rotate 90 degrees
        column.HeaderStyle = (Style)dgMatrix.Resources["HeaderRotateStyle"];
        column.Width = DataGridLength.Auto;
        dgMatrix.Columns.Add(column);
    }


    //this method builds the template for each column in order to properly bind the rectangles to their color
    private static DataTemplate CreateFactViewModelTemplate(int index)
    {
        string xamlTemplateFormat =
            @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
            <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column=""0"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].LeftForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].LeftColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].LeftScore,Mode=OneWay}"" />
            <TextBlock Grid.Column=""1"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].RightForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].RightColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].RightScore,Mode=OneWay}"" />
            </Grid>
            </DataTemplate>";




        string xamlTemplate = xamlTemplateFormat.Replace("~Index~", index.ToString());

        return (DataTemplate)XamlReader.Parse(xamlTemplate);
    }
4b9b3361

Ответ 1

Поскольку я не вижу ваш исходный код, вам очень сложно помочь. Тем более, что на производительность приложения WPF влияет множество вещей. Для некоторых советов о том, что следует искать, см. Оптимизация производительности приложения WPF. И да - это очень важно, какой xaml используется в каждой ячейке. Потому что обычно проблемы с производительностью сводятся к "слишком большому количеству элементов". Знаете ли вы, что TextBox я считаю 30 отдельных элементов? Я рекомендую вам использовать Performance Profiling Tools для WPF, чтобы узнать больше о вашей конкретной проблеме. Постарайтесь минимизировать количество элементов, которые вы используете (например, переключаясь с TextBox на TextBlock, если это необходимо).

Также вы должны проверить, существуют ли проблемы с производительностью на любом ПК, на котором вы пытаетесь включить приложение. Возможно, ПК, который вы используете, заставляет WPF в программном рендеринге. Или вы используете BitmapEffects?

Edit:
Глядя на свой код, я предлагаю вам изменить

column.Width = DataGridLength.Auto;

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

Ответ 2

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

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

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

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

Ответ 3

в одном из моих проектов следующая настройка стиля сетки вызывала серьезную проблему с производительностью:

 <Style  TargetType='{x:Type controls:DataGrid}'>
    <Setter Property='ScrollViewer.CanContentScroll' Value='False' />
    ...

Когда я удалил параметр ScrollViewer.CanContentScroll, проблема с производительностью исчезла.

Ответ 4

Есть ли у вас какой-либо планшет любого типа (через USB или планшетный ПК)?

Я обнаружил ошибку производительности в WPat datagrid при использовании планшета. Я разместил видео, и он подтвержден MS здесь, в этом потоке

Cheers, Джон

Ответ 5

У меня был случай, когда мой базовый объект имел свойство только с установщиком. Такое же свойство было доступно путем реализации ITypedList в коллекции и через TypeDescriptionProvider/ICustomTypeDescriptor для отдельных объектов. Либо удаление свойства, либо добавление геттера разрешили проблемы с производительностью.

Ответ 6

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

Вы также можете попробовать опцию "Отложенная прокрутка" в последнем WPat Datagrid.