更新信息好的,抱歉,我不得不检查我的问题和标题。但是,尽管我们进行了多次测试,但问题的缩小范围并不容易追踪。您会在下面找到导致无法解释的错误的新代码,以及由于遗留原因而留下的旧版本问题。这个问题很容易重现。
更新代码
绑定Listview
到 anObservableCollection
并用大量项目填充它,在我们的例子中超过 30k 左右。最终结果是,当您增加项目数量时,ItemsStackPanel
中的ListView
扩展超出包含网格。它发生在 的两个方向上,ItemsStackPanel
但当方向设置为 时更容易发生Horizontal
。
我们的问题是如何解决这个问题,即在不丢失虚拟化的情况下避免流出包含网格?
请注意,我们需要处理如此多的文件,因为我们正在构建一个照片应用程序,在该应用程序中通常要显示数以万计的图像/视频。除了这个错误,UWP 应用实际上在所有问题上都对此做出了很好的响应。
谢谢
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Background="LightGreen">
<ListView
ItemsSource="{x:Bind Items}"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="Not working"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
C#
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Items = new ObservableCollection<string>();
for (int i = 0; i < 30000; i++)//Increase length here
{
Items.Add($"Item 1");
}
}
public ObservableCollection<string> Items { get; }
}
旧代码(跳过它)
以下代码显示 2 ListView
,只有一个区别:
第一个 ListView 将 绑定ItemsSource
到CollectionViewSource.View
源设置为 a 的 a FileInformationFactory
。下面的 UI 显示了一个按钮,可以选择 100 多张图片来填充它ListView
(请参阅编辑部分)。
第二个 ListView 将 绑定ItemsSource
到另一个CollectionViewSource.View
,其源设置为 trivial ObservableCollection
。
结果
ItemsStackPanel
只要' 的方向设置为,第一个 ListView 就会超出网格容器Horizontal
。切换 ItemsSource 并没有解决这个问题,因此表明这个问题是特定于FileInformationFactory.GetVirtualizedFilesVector()
方法的。
问题
如何在不丢失虚拟化的情况下解决这个问题?
谢谢
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="1" Orientation="Horizontal">
<AppBarButton Icon="Folder"
LabelPosition="Collapsed"
Click="FolderPickerButton_Click"/>
</StackPanel>
<Grid Grid.Row="1" Background="LightGreen">
<ListView
ItemsSource="{x:Bind CollectionViewSource.View, Mode=OneWay}"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="Not working" TextWrapping="WrapWholeWords"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<Grid Grid.Row="2" Background="Yellow">
<ListView
ItemsSource="{x:Bind WorksCollectionViewSource.View, Mode=OneWay}"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="Working" TextWrapping="WrapWholeWords"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
C#
public sealed partial class Scenario5 : Page
{
public Scenario5()
{
this.InitializeComponent();
Items = new ObservableCollection<string>();
for (int i = 0; i < 30000; i++)
{
Items.Add($"Item 1");
}
CollectionViewSource = new CollectionViewSource();
WorksCollectionViewSource = new CollectionViewSource();
}
private StorageFolder _folder;
private QueryOptions _queryOptions;
private StorageFileQueryResult _query;
private FileInformationFactory _fileInformationFactory;
public CollectionViewSource CollectionViewSource { get; set; }
public CollectionViewSource WorksCollectionViewSource { get; set; }
public ObservableCollection<string> Items { get; }
private async void FolderPickerButton_Click(object sender, RoutedEventArgs e)
{
var _pickedFolder = await PickFolderAsync();
if (_pickedFolder == null)
{
return;
}
_folder = _pickedFolder;
_queryOptions = new QueryOptions
{
FolderDepth = FolderDepth.Deep,
IndexerOption = IndexerOption.UseIndexerWhenAvailable,
};
_query = _folder.CreateFileQueryWithOptions(_queryOptions);
_fileInformationFactory = new FileInformationFactory(_query, ThumbnailMode.SingleItem, 160,
ThumbnailOptions.UseCurrentScale, delayLoad: false);
var _vector = _fileInformationFactory.GetVirtualizedFilesVector();
CollectionViewSource.Source = _vector;
WorksCollectionViewSource.Source = Items;
}
private static async Task<StorageFolder> PickFolderAsync()
{
var folderPicker = new FolderPicker
{
SuggestedStartLocation = PickerLocationId.Desktop,
ViewMode = PickerViewMode.Thumbnail
};
folderPicker.FileTypeFilter.Add("*");
var _pickedFolder = await folderPicker.PickSingleFolderAsync();
return _pickedFolder;
}
}
编辑
问题已经缩小。这不是FileInformationFactory
. ObservableCollection
有大量物品(在我的情况下约为 30k)也会出现问题,请参阅后面代码中的 ctor。在这个数字之下,所有项目都在网格内,而在这个数字之上,它们就离开了父容器。