Виртуализация пользовательского элемента управления WPF - PullRequest
0 голосов
/ 05 марта 2020

Я реализую свой собственный элемент управления на основе Grid (, а не DataGrid). Этот элемент управления отображает содержимое DataTable и поддерживает выбор столбцов, строк и элементов (причина неиспользования DataGrid заключается в сложности таких манипуляций). Он наполняется такими элементами:

private void DrawGrid(DataTable table)
{
    // grdMain stays for the grid itslef
    grdMain.RowDefinitions.Clear();
    grdMain.ColumnDefinitions.Clear();
    var padding = new Thickness(5, 2, 5, 2);

    for (int colNumber = 0; colNumber <= table.Columns.Count; colNumber++)
    {
        //Here comes logic for ColumnDefinitions addition
    }

    //First row is for table header
    grdMain.RowDefinitions.Add(new RowDefinition());
    //Main loop where the whole stuff gets added into the table
    for (int rowNumber = 1; rowNumber <= table.Rows.Count; rowNumber++)
    {
        grdMain.RowDefinitions.Add(new RowDefinition());
        // First column is for row numbers
        for (int colNumber = 1; colNumber <= table.Columns.Count; colNumber++)
        {
            //grdMain.Children.Add(CreateHeaderTextBlock(rowNumber.ToString(), 0, rowNumber, false));
            //grdMain.Children.Add(CreateColumnHeaderRectangle(0, rowNumber));
            var cellTextBlock = new TextBlock()
            {
                Text = table.Rows[rowNumber - 1][colNumber - 1].ToString(),
                Padding = padding
            };

            grdMain.Children.Add(cellTextBlock);
            cellTextBlock.SetValue(Grid.RowProperty, rowNumber);
            cellTextBlock.SetValue(Grid.ColumnProperty, colNumber);
        }
    }
}

Код довольно прост, но ему не хватает виртуализации элементов. Для таблицы 1000x10 на рендеринг уходит более 3 секунд, а узким местом является макет.

Есть идеи о том, как реализовать виртуализацию? Сетка grdMain находится в ScrollViewer, что позволяет прокручивать эту сетку. Теоретически я мог бы загрузить новые элементы и добавить их при прокрутке, но я не уверен, будут ли полосы прокрутки работать правильно.

UPD: DataTable, который передается как параметр, ничего, кроме BindableProperty:

public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(DataTable), typeof(TableSelector),
            new FrameworkPropertyMetadata(new DataTable(), OnItemsSourceChanged));

public DataTable ItemsSource
{
    get => (DataTable)GetValue(ItemsSourceProperty);
    set => SetValue(ItemsSourceProperty, value);
}

Обратный вызов OnItemsSourceChanged вызывает метод DrawGrid для повторного рендеринга таблицы.

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