Просмотр сетки в ListView с большим количеством строк, столбцов и шаблонов ячеек

#wpf #xaml #listview #gridview #celltemplate

#wpf #xaml #listview #просмотр сетки #celltemplate

Вопрос:

У меня проблема с моим ListView / GridView. Фактически, моя сетка содержит 285 строк и 24 столбца, построенных динамически.

Моя сетка была настолько медленной, что я решил выполнить некоторые другие тесты непосредственно в XAML (что теоретически должно быть более эффективным). Все столбцы имеют CellTemplate.

Вы можете легко воспроизвести проблему с этим :

 <Window x:Class="WpfApplication2.HighColumns"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="HighColumns" Height="300" Width="300">
<Window.Resources>
    <DataTemplate x:Key="myCellTemplateMonth">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                <TextBlock Grid.Column="0" Text="{Binding}"/>
            </Border>
            <Border Grid.Column="1" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                <TextBlock Grid.Column="0" Text="{Binding}"/>
            </Border>
        </Grid>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ListView Background="Transparent" BorderThickness="0" Name="lv2" Grid.Column="1">
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.View>
            <GridView x:Name="gv1">
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                    <!--<GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>              
                                <Border Grid.Column="0" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                                    <TextBlock Grid.Column="0" Text="{Binding}"/>
                                </Border>
                                <Border Grid.Column="1" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                                    <TextBlock Grid.Column="0" Text="{Binding}"/>
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>-->
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
                <GridViewColumn Width="300" Header="Indics" CellTemplate="{StaticResource myCellTemplateMonth}">
                </GridViewColumn>
            </GridView>
        </ListView.View>
        <sys:DateTime>1/2/3</sys:DateTime>
        <sys:DateTime>4/5/6</sys:DateTime>
        <sys:DateTime>7/8/9</sys:DateTime>
        <sys:DateTime>10/11/12</sys:DateTime>
        [paste the previous 4 ligns here in order to have around 300 rows]
    </ListView>
</Grid>
  

Вы можете видеть стиль «двойной колонки» в каждом столбце (с небольшой графической ошибкой, но не обращайте внимания на этот факт).

Основной проблемой здесь является МЕДЛЕННАЯ работа сетки, ее явно нельзя использовать в качестве профессиональной сетки… Я попытался активировать виртуализацию и отключить ее (когда виртуализация отключена, загрузка сетки занимает около 17-18 секунд …)

Есть ли какие-то хитрости для достижения высокоскоростной сетки или я что-то делаю неправильно? Сначала я использовал WPF Toolkit Datagrid (я использую WPF 3.5 с Windows XP), и у меня возникла та же проблема, поэтому, поскольку я хочу отображать только данные (и вообще без редакции), я вернулся к «старомодному» ListView с GridView внутри … без эффекта, ИМХО..

Спасибо!

РЕДАКТИРОВАТЬ 1: Кажется, что я достиг максимума возможностей производительности WPF GridView… Пример, написанный ранее, представляет собой всего лишь «простой» список… Учтите, что я привязываю не просто строку, а словарь и сложную структуру. Кроме того, все это приложение WPF представляет собой библиотеку классов, запускаемую надстройкой VSTO.

Вывод: gridview как есть непригоден для использования … и загружается через 22 секунды, когда я отключаю виртуализацию.

Похоже, мне придется использовать WinForm DataGridView в моем окне WPF… Как вы думаете, проблему можно решить с помощью этого?

Комментарии:

1. На моем компьютере VirtualizingStackPanel. IsVirtualizing =»True» в ListView позволяет загружать его за 1 секунду. Виртуализацияstackpanel. IsVirtualizing=»False» занимает 6-8 секунд. Кстати, зачем вам так много строк и столбцов? Что это за данные?

2. Столбцы генерируются динамически (один столбец = один год), и это таблица «сравнения» (для каждого столбца есть 2 вложенных столбца — до / после). Строки — это то, о чем я не могу вам рассказать, но какими бы ни были данные (я тестировал с некоторыми строками), проблема по-прежнему остается той же. Когда вы пытались с VirtualizingStackPanel. IsVirtualizing = «True», вы чувствовали, что вертикальная прокрутка происходит чрезвычайно медленно?

3. лишь небольшое замедление (приемлемое), но не чрезвычайно. Ваш компьютер довольно старый?

4. Pentium 4 2,80 ГГц, 3 ГБ оперативной памяти, Windows XP SP3. Проблема здесь в том, что мое приложение будет развернуто на компьютерах менее мощных, чем у меня, поэтому оно будет, по крайней мере, таким же, и даже худшим!

5. Я изменил свой первоначальный пост…

Ответ №1:

Вы уверены, что проблема в GridView? Я помню из более старого проекта, что я без проблем визуализировал огромные сетки (до 100 столбцов).
Попробуйте удалить привязку из вашей таблицы данных и попробуйте, работает ли она медленно без привязок. Если нет, проблема заключается в методе toString() ваших исходных объектов.

 <DataTemplate x:Key="myCellTemplateMonth">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                <TextBlock Grid.Column="0" Text="Test withouth binding"/>
            </Border>
            <Border Grid.Column="1" BorderThickness="1,0,1,1" SnapsToDevicePixels="True" BorderBrush="Black" Margin="-6,0,-6,0">
                <TextBlock Grid.Column="0" Text="Test withouth binding"/>
            </Border>
        </Grid>
    </DataTemplate>
  

Комментарии:

1. Вместо этого я попробовал с <TextBlock Grid.Column="0" Text="ok"/> . это просто немного менее медленно, но все еще не используется корректно : (