Производительность WPF Datagrid - PullRequest
31 голосов
/ 30 марта 2009

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

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

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

 private void AddColumn(string s, int index)
    {
        DataGridTemplateColumn column = new DataGridTemplateColumn();
        column.Header = s;
        //Set template for inner cell's 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);
    }

Ответы [ 6 ]

20 голосов
/ 30 марта 2009

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

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

Edit:
Глядя на ваш код, я бы посоветовал вам изменить

column.Width = DataGridLength.Auto;

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

10 голосов
/ 14 сентября 2011

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

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

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

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

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

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

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

1 голос
/ 03 ноября 2012

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

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

1 голос
/ 23 ноября 2011

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

1 голос
/ 21 апреля 2009

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

Я обнаружил ошибку производительности в таблице данных WPF при использовании планшета. Я разместил видео, и оно подтверждено MS здесь, в этой теме

Ура, Jon

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