Неблагоразумное время загрузки WPF DataGrid

У меня всегда были долго загружающиеся времена с WPF DataGrids, и я не могу найти подобные отчеты онлайн, таким образом, я подозревал, что делал что-то не так. Теперь я уверен в нем, так как добавляющая сложность расположения значительно замедляет выполнение. В очень простом макете DataGrid заполняет мгновенно, тогда как код ниже взятий приблизительно 3 секунды для выполнения.

В следующем коде требуется ~3 секунды для 150 строк и 11 столбцов для загрузки, даже если каждая ячейка не связывается ни с каким свойством и с AutoGenerateColumns=False. (У меня есть два ядра, процессор на 2.6 ГГц с большим количеством RAM).

Горлышко бутылки происходит, когда свойство ItemsSource установлено в расположении как то ниже:

<Window x:Class="datagridtest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Border  Background="LightSteelBlue" CornerRadius="10" Margin="10">
    <ScrollViewer Margin="10" HorizontalScrollBarVisibility="Auto">
        <Grid Margin="10,50,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"  />
                <RowDefinition Height="auto" />
                <RowDefinition Height="auto" />

            </Grid.RowDefinitions>
            <Expander IsExpanded="True" Name="expander1"  Grid.Row="0">
                <Grid>
                    <DataGrid VirtualizingStackPanel.IsVirtualizing="True" AutoGenerateColumns="false" Name="dg" Height="auto" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False">
                        <DataGrid.Columns>
                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>



                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>


                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>

                            <DataGridTextColumn >
                                <DataGridTextColumn.Header >
                                    <TextBlock Width="140" HorizontalAlignment="Center" TextAlignment="Center">untitled<LineBreak/>column</TextBlock>
                                </DataGridTextColumn.Header>
                            </DataGridTextColumn>



                        </DataGrid.Columns>
                        </DataGrid>
                </Grid>
            </Expander>

            <Expander IsExpanded="true"  Grid.Row="1">
                <Grid>
                    <DataGrid AutoGenerateColumns="True"  Height="auto" />
                </Grid>
            </Expander>

            <Expander IsExpanded="true"    Grid.Row="2">
                <Grid>
                    <DataGrid AutoGenerateColumns="True" Height="auto" />
                </Grid>
            </Expander>
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="121,-42,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click_2" />
        </Grid>
    </ScrollViewer>
</Border>

using System.Collections.ObjectModel;

namespace datagridtest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();


    }

    class row
    {
        public string Name { get; set; }
        public double Age { get; set; }
    }



    private void button1_Click_2(object sender, RoutedEventArgs e)
    {
        ObservableCollection<row> src = new ObservableCollection<row>();

        for (int i = 0; i < 150; i++)
            src.Add(new row { Name = i.ToString(), Age = i / 2 });

        dg.ItemsSource = src;
    }
}
}
9
задан Eugenio De Hoyos 26 July 2010 в 17:20
поделиться

2 ответа

Проблема возникает только тогда, когда DataGrid встроен в ScrollViewer, например:

<ScrollViewer>
    <Datagrid/>
</ScrollViewer>

Это имеет смысл, потому что эта конфигурация заставляет всю DataGrid рисоваться одновременно (чтобы иметь возможность изменять размер клиентская область ScrollViewer правильно). По сути, он переопределяет встроенное поведение виртуализации DataGrid, которое реализует свои собственные полосы прокрутки, так что не все его содержимое должно быть размещено в макете одновременно.

Другими словами, встраивание DataGrid в ScrollViewer требуется редко, потому что DataGrid имеет собственную автоматическую прокрутку.

17
ответ дан 4 December 2019 в 08:32
поделиться

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

Также попробуйте VirtualizingStackPanel.VirtualizationMode = "Recycling", чтобы позволить ему повторно использовать используемые шаблоны.

3
ответ дан 4 December 2019 в 08:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: