在Windows Phone 8.1的列表视图摆动,而滚动,虽然长列表(XAML)

本文关键字:列表 滚动 XAML Phone Windows 视图 | 更新日期: 2023-09-27 18:09:46

我在Windows Phone 8.1应用程序中滚动ListView时遇到了问题。短列表滚动得很好,滚动得很顺利,但是一旦虚拟化启动,整个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>

在Windows Phone 8.1的列表视图摆动,而滚动,虽然长列表(XAML)

所以这似乎是一个操作系统的问题,正如在这个线程在微软论坛: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.

问题确实存在于虚拟化中,项目没有固定的宽度。使用星号作为宽度或使水平对齐拉伸不起作用,所以考虑方向和分辨率的唯一解决方案是将宽度绑定到ListView的容器的ActualWidth属性:

<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>

不显示listview中的第一个元素,因为在加载页面时,Grid的actialwidth在第一秒为0。这就是我的解决方案:

<Grid x:Name="contentRoot" Margin="20">
<ListView>
 <ListView.ItemTemplate>
   <DataTemplate>
     <Grid MinWidth="{Binding ActualWidth, ElementName=contentRoot}" />
   </DataTemplate>
 </ListView.ItemTemplate>
</ListView>
</Grid>

这是一个非常恼人的bug。我不明白为什么这么多年都没有解决这个问题。

在垂直滚动列表视图中拉伸项目是一个非常基本的功能,应该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更改为自定义列表视图类型比编辑每个数据模板等工作更少,更干净。我的两分钱。

我的做法似乎有效。至少在WP8.1中是这样。

明确设置<ListView></ListView>块中的ItemsPanelTemplate,但不使用

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>

VirtualizingStackPanel设置中的HorizontalContentAlignmentWidth用于将ListView中的内容居中,您可以自由移动这些设置。我不知道为什么,但它确实有效。

Windows 10对Windows 8.1应用程序的修复