Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Page x:Class="CollectionsExperiment.Samples.IncrementalLoadingCollectionSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CollectionsExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid MaxWidth="460"
HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Left">
<TextBlock Text="Items are loaded incrementally when the view needs to show them (i.e., when the user scrolls the ListView)"
TextWrapping="Wrap" />
<Button Margin="0,12,0,12"
Click="{x:Bind PeopleSource.RefreshAsync}"
Content="Refresh collection"
Style="{StaticResource AccentButtonStyle}" />
<TextBlock>
<Run Text="Is loading:" />
<Run FontWeight="SemiBold"
Text="{x:Bind PeopleSource.IsLoading, Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run Text="Has more items:" />
<Run FontWeight="SemiBold"
Text="{x:Bind PeopleSource.HasMoreItems, Mode=OneWay}" />
</TextBlock>
</StackPanel>
<Grid Grid.Row="2"
MaxHeight="420"
Margin="0,24,0,0"
VerticalAlignment="Top"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="4">
<ListView x:Name="PeopleListView"
ItemsSource="{x:Bind PeopleSource, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Person">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Width="24"
Height="24"
VerticalAlignment="Center"
Source="ms-appx:///Assets/AppIcon.png" />
<TextBlock Grid.Column="1"
Margin="12"
VerticalAlignment="Center"
Text="{x:Bind Name}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</Page>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.WinUI.Collections;
namespace CollectionsExperiment.Samples;
[ToolkitSample(id: nameof(IncrementalLoadingCollectionSample), "Incremental Loading Collection", description: $"A sample for showing how to create and use a IncrementalLoadingCollection.")]
public sealed partial class IncrementalLoadingCollectionSample : Page
{
// IncrementalLoadingCollection can be bound to a GridView or a ListView. In this case it is a ListView called PeopleListView.
public IncrementalLoadingCollection<PeopleSource, Person> PeopleSource { get; set; } = new(new PeopleSource());
public IncrementalLoadingCollectionSample()
{
this.InitializeComponent();
}
}
/// <summary>
/// A sample implementation of the <see cref="IIncrementalSource{TSource}"/> interface.
/// </summary>
/// <seealso cref="IIncrementalSource{TSource}"/>
public partial class PeopleSource : IIncrementalSource<Person>
{
private readonly List<Person> _people;
/// <summary>
/// Initializes a new instance of the <see cref="PeopleSource"/> class.
/// </summary>
public PeopleSource()
{
// Creates an example collection.
_people = new List<Person>();
for (int i = 1; i <= 200; i++)
{
var p = new Person { Name = "Person " + i };
_people.Add(p);
}
}
/// <summary>
/// Retrieves items based on <paramref name="pageIndex"/> and <paramref name="pageSize"/> arguments.
/// </summary>
/// <param name="pageIndex">
/// The zero-based index of the page that corresponds to the items to retrieve.
/// </param>
/// <param name="pageSize">
/// The number of <see cref="Person"/> items to retrieve for the specified <paramref name="pageIndex"/>.
/// </param>
/// <param name="cancellationToken">
/// Used to propagate notification that operation should be canceled.
/// </param>
/// <returns>
/// Returns a collection of <see cref="Person"/>.
/// </returns>
public async Task<IEnumerable<Person>> GetPagedItemsAsync(int pageIndex, int pageSize, CancellationToken cancellationToken = default(CancellationToken))
{
// Gets items from the collection according to pageIndex and pageSize parameters.
var result = (from p in _people
select p).Skip(pageIndex * pageSize).Take(pageSize);
// Simulates a longer request...
// Make sure the list is still in order after a refresh,
// even if the first page takes longer to load
if (pageIndex == 0)
{
await Task.Delay(2000);
}
else
{
await Task.Delay(1000);
}
return result;
}
}
/// <summary>
/// A sample class used to show how to use the <see cref="IIncrementalSource{TSource}"/> interface.
/// </summary>
public partial class Person
{
/// <summary>
/// Gets or sets the name of the person.
/// </summary>
public string? Name { get; set; }
}
IIncrementalSource - An interface that represents a data source whose items can be loaded incrementally.
IncrementalLoadingCollection - An extension of ObservableCollection such that its items are loaded only when needed.
Example
IIncrementalSource allows to define the data source:
// Be sure to include the using at the top of the file:
//using CommunityToolkit.WinUI.Collections;
public class Person
{
public string Name { get; set; }
}
public class PeopleSource : IIncrementalSource<Person>
{
private readonly List<Person> people;
public PeopleSource()
{
// Creates an example collection.
people = new List<Person>();
for (int i = 1; i <= 200; i++)
{
var p = new Person { Name = "Person " + i };
people.Add(p);
}
}
public async Task<IEnumerable<Person>> GetPagedItemsAsync(int pageIndex, int pageSize)
{
// Gets items from the collection according to pageIndex and pageSize parameters.
var result = (from p in people
select p).Skip(pageIndex * pageSize).Take(pageSize);
// Simulates a longer request...
await Task.Delay(1000);
return result;
}
}
The GetPagedItemsAsync method is invoked every time the view need to show more items.
IncrementalLoadingCollection can then be bound to a ListView or a GridView-like control:
var collection = new IncrementalLoadingCollection<PeopleSource, Person>();
PeopleListView.ItemsSource = collection;
Windows Community Toolkit