ListView в Windows Phone 8.1 Во время прокрутки длинного списка (XAML)
У меня возникают проблемы с прокруткой списков в моем приложении Windows Phone 8.1. Короткие списки прокручиваются просто отлично, прокручивая гладко, но как только Виртуализация ударит по всему элементу ListView "качается" влево немного, но достаточно заметна, чтобы раздражать.
Я попытался удалить все переходы без каких-либо эффектов, а также с постепенным увеличением количества элементов. Установка панели элементов в StackPanel (удаление виртуализации) устраняет проблему, но не является предпочтительной.
Мои списки являются привязкой к свойству в DefaultViewModel, который поставляется с основным шаблоном страницы.
Что я делаю неправильно и что вызывает у моего ListViews такое поведение?
XAML:
<ListView x:Name="searchResultsList" IsItemClickEnabled="True" ItemClick="ListView_ItemClick" ItemsSource="{Binding searchResults}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,0,0,20" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Width="80" Height="80">
<Image Source="{Binding Image}" />
</Border>
<StackPanel Grid.Column="2">
<TextBlock Text="{Binding PodcastTitle}" TextWrapping="WrapWholeWords" FontSize="{StaticResource TextStyleExtraLargeFontSize}" />
<TextBlock Text="{Binding LastUpdated, Converter={StaticResource dateConverter}}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
<TextBlock Text="{Binding PodcastArtist}" TextWrapping="WrapWholeWords" Style="{ThemeResource ListViewItemContentTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Ответы
Ответ 1
Так что это проблема ОС, о чем свидетельствует этот поток на форумах MS: http://social.msdn.microsoft.com/Forums/en-US/9a363d33-5760-4d38-9c81-84259c4edcbe/listview-jiggles-horizontally-when-large-item-about-to-scroll-in-or-out-in-windows-phone-81-preview?forum=WindowsPhonePreviewSDK&prof=required.
Проблема действительно заключается в виртуализации с элементами, которые не имеют фиксированной ширины. Использование звезды в качестве ширины или выравнивание по горизонтали не будет работать, поэтому единственным решением, которое учитывает ориентацию и разрешение, было привязать ширину к свойству ActualWidth контейнера ListView:
<Grid x:name="contentRoot" Margin="19,9.5,19,0">
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width={Binding ActualWidth, ElementName=contentRoot} />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Ответ 2
Первый элемент в списке не отображается, потому что ActiualWidth Grid равен 0 в первую секунду при загрузке страницы. Это решение, которое работает для меня:
<Grid x:Name="contentRoot" Margin="20">
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid MinWidth="{Binding ActualWidth, ElementName=contentRoot}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Ответ 3
Это очень раздражающая ошибка. Я не могу понять, почему это не фиксируется с годами.
Элементы растяжения Imho в вертикальном списке прокрутки являются очень базовой функцией и должны работать на 100%.
Возможное обходное решение также обрезается, что также должно быть известно о изменениях размера:
public class StrechItemsListView : ListView
{
public StrechItemsListView()
{
SizeChanged += StrechItemsListView_SizeChanged;
}
private void StrechItemsListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ItemsPanelRoot != null)
{
ItemsPanelRoot.Width = e.NewSize.Width;
}
}
}
Изменение xaml только для пользовательского типа списка меньше работы и очистки, а затем редактирования каждого datatemplate и т.д. Только мои 2 цента.
Ответ 4
Моя практика, похоже, работает. По крайней мере, в WP8.1
.
Просто установите ItemsPanelTemplate
в блоке <ListView></ListView>
явно, но не используйте
Style="{StaticResource ListViewStyle1}"
или что-то еще.
Пример кода:
<ListView ItemsSource="{Binding RadioList}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollMode="Auto">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="10,3,10,0">
<TextBlock Text="{Binding RadioName}" FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" Width="{Binding PhoneWidth}"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Настройки HorizontalContentAlignment
и Width
из VirtualizingStackPanel
используются для центрирования содержимого в ListView
. Вы можете свободно перемещать эти настройки. Я не знаю, почему, но он работает.
Ответ 5
Это было исправлено в приложениях Windows 10 для Windows 8.1