ListView в Windows Phone 8.1 колеблется при прокрутке длинного списка (XAML)

#c# #xaml #windows-runtime #windows-phone-8.1

#c# #xaml #windows-среда выполнения #windows-phone-8.1

Вопрос:

У меня возникли проблемы с прокруткой списков просмотра в моем приложении Windows Phone 8.1. Короткие списки прокручиваются просто отлично, прокручиваются плавно, однако, как только запускается виртуализация, весь ListView слегка «колеблется» влево, но достаточно заметно, чтобы раздражать.

Я пытался удалить все переходы безрезультатно, а также загружать элементы постепенно, но безуспешно. Установка панели элементов на StackPanel (удаление виртуализации) устраняет проблему, но не является предпочтительной.

Мои listviews привязаны к свойству в DefaultViewModel, которое поставляется с базовым шаблоном страницы.

Что я делаю не так и что заставляет мои просмотры списков демонстрировать такое поведение?

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. Так что «колебания» — это то, что нужно было поискать в Google… Я не мог понять, как описать это явление …!

2. @FactorMystic Здесь то же самое. Я не знал, что искать. Я думаю, именно по этой причине этот вопрос не привлекает достаточного внимания.

Ответ №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=WindowsPhonePreviewSDKamp;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>
 

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

1. Это приведет к тому, что мой первый элемент в списке не будет отображаться, какие-либо предложения?

2. Использовал его для UserControl, и все было хорошо, но вдруг я заметил, что эта привязанная ширина не соответствует ширине корня при изменениях времени выполнения, таких как рейтинг устройства. Корневые полосы отображаются в альбомной ориентации, а элементы списка — нет. Могу ли я что-нибудь с этим сделать?

3. Как насчет того, что ItemTemplate был определен выше, и у вас есть только ItemTemplateSelector. Я попробовал это, но, похоже, ItemTemplate не может привязываться к ширине сетки контейнера. Я застрял здесь.

4. <ListView Grid.Row="1" x:Name="ListViewEvents" Loaded="OnListViewEventsLoaded" ItemsSource="{Binding xx}" ItemTemplateSelector="{StaticResource xx}" ItemContainerStyle="{StaticResource xx}" IsItemClickEnabled="True"> Вот так, как же тогда использовать этот метод? Спасибо!

Ответ №2:

Первый элемент в listview не отображается, потому что ActualWidth сетки равен 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 только на пользовательский тип listview требует меньше работы и чище, Чем редактирование каждой таблицы данных и т. Д. Только мои 2 цента.

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

1. Спасибо, это помогло! Просто и быстро!

Ответ №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