#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"/>
. это просто немного менее медленно, но все еще не используется корректно : (