From 0a0b233f671c559e5c0b05975a524a250079ca7a Mon Sep 17 00:00:00 2001 From: hippieZhou Date: Sun, 22 Sep 2024 21:57:38 +0800 Subject: [PATCH] Generate new post --- ...ew-support-IncrementalLoading-in-WinUI3.md | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/source/_posts/how-to-make-ItemsView-support-IncrementalLoading-in-WinUI3.md diff --git a/src/source/_posts/how-to-make-ItemsView-support-IncrementalLoading-in-WinUI3.md b/src/source/_posts/how-to-make-ItemsView-support-IncrementalLoading-in-WinUI3.md new file mode 100644 index 0000000..88cdf65 --- /dev/null +++ b/src/source/_posts/how-to-make-ItemsView-support-IncrementalLoading-in-WinUI3.md @@ -0,0 +1,142 @@ +--- +title: How to make ItemsView support IncrementalLoading in WinUI3 +date: 2024-09-22 21:40:01 +tags: WinUI3 +--- + +> 在 WinUI3 中新增的 **ItemsView** 控件本身不支持 `IncrementalLoading` 进行增量加载,本文通过实现一个自定关于的 Behavior 方式来解决这个问题。 + +# ItemSource 的定义 + +```C# +public class Person +{ + public string Name { get; set; } +} + +public class PeopleSource : IIncrementalSource +{ + private readonly List people; + + public PeopleSource() + { + // Creates an example collection. + people = new List(); + + for (int i = 1; i <= 200; i++) + { + var p = new Person { Name = "Person " + i }; + people.Add(p); + } + } + + public async Task> 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; + } +} + +``` + +# IncrementalLoadingBehavior 的实现 + +```C# +public class IncrementalLoadingBehavior : Behavior +{ + private ScrollViewer? scrollViewer; + + public static readonly DependencyProperty LoadMoreItemsCommandProperty = + DependencyProperty.Register(nameof(LoadMoreItemsCommand), typeof(ICommand), typeof(IncrementalLoadingBehavior), new PropertyMetadata(null)); + + public ICommand LoadMoreItemsCommand + { + get => (ICommand)GetValue(LoadMoreItemsCommandProperty); + set => SetValue(LoadMoreItemsCommandProperty, value); + } + + protected override void OnAttached() + { + base.OnAttached(); + AssociatedObject.Loaded += OnLoaded; + } + + protected override void OnDetaching() + { + base.OnDetaching(); + AssociatedObject.Loaded -= OnLoaded; + if (scrollViewer != null) + { + scrollViewer.ViewChanged -= OnViewChanged; + } + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + scrollViewer = AssociatedObject.FindAscendant(); + if (scrollViewer != null) + { + scrollViewer.ViewChanged += OnViewChanged; + } + } + + private void OnViewChanged(object? sender, ScrollViewerViewChangedEventArgs e) + { + if (scrollViewer != null && + scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight - 100) + { + LoadMoreItemsCommand?.Execute(null); + } + } +} + +// ViewModel.cs +public Items { get; private set; } = new IncrementalLoadingCollection(); + +[RelayCommand] +private async Task OnLoadMoreItemsAsync() +{ + if (Items != null && Items.IsLoading == false) + { + await Items.LoadMoreItemsAsync(10); + } +} + +[RelayCommand] +private void OnItemInvoked(ItemsViewItemInvokedEventArgs invokedItem) +{ + var selected = invokedItem.InvokedItem as Person; +} +``` + +# ItemsView 的集成 + +```XAML + + + + + + + + + + + + + ...... + + + + + + +``` \ No newline at end of file