maui中实现加载更多 RefreshView跟ListView(2)

一个类似商品例表的下拉效果:

代码

新增个类为商品商体类

csharp 复制代码
    public class ProductItem
    {
        public string ImageSource { get; set; }
        public string ProductName { get; set; }
        public string Price { get; set; }
    }

界面代码:

xml 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://schemas.microsoft.com/dotnet/2021/maui/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             BackgroundColor="{DynamicResource PageBackgroundColor}"
             x:Class="fenye.MainPage">

    <RefreshView IsRefreshing="{Binding IsRefreshing}"  
                 Command="{Binding RefreshCommand}">
        <StackLayout Margin="10">
            <ListView ItemsSource="{Binding Items}" ItemAppearing="OnItemAppearing"  RowHeight="70" Margin="20">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <!-- 第一列宽度自适应 -->
                                    <ColumnDefinition Width="*" />
                                    <!-- 第二列宽度填充剩余空间 -->
                                </Grid.ColumnDefinitions>
                                <!-- 左侧图片 -->
                                <Image Source="{Binding ImageSource}" 
                                       Aspect="AspectFit"
                                       WidthRequest="150"
                                       HeightRequest="150"  Grid.Column="0" />

                                <!-- 右侧商品名和价格 -->
                                <StackLayout Grid.Column="1" Margin="10">
                                    <Label Text="{Binding ProductName}" 
                                           FontAttributes="Bold"
                                           FontSize="18"/>
                                    <Label Text="{Binding Price}" 
                                           FontSize="16" 
                                           TextColor="Green"/>
                                </StackLayout>
                            </Grid>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </RefreshView>
</ContentPage>

后端代码:

csharp 复制代码
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace fenye
{

    public class ProductItem
    {
        public string ImageSource { get; set; }
        public string ProductName { get; set; }
        public string Price { get; set; }
    }



    // 标记 XAML 编译选项
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage : ContentPage
    {
        // 数据源,用于存储列表项的集合
        private ObservableCollection<ProductItem> _items;

        // 是否正在刷新的标志
        private bool _isRefreshing;
        public ObservableCollection<ProductItem> Items => _items;

        // 随机数生成器
        private Random _random = new Random();
        // 各类水果数组
        private string[] fruits = { "苹果", "香蕉", "橙子", "葡萄", "草莓", "梨", "桃子", "西瓜", "蓝莓", "樱桃" };

        // 构造函数,初始化页面
        public MainPage()
        {
            InitializeComponent();
            BindingContext = this;

            // 初始化数据源并填充一些初始数据
            _items = new ObservableCollection<ProductItem>();
            for (int i = 0; i < 20; i++)
            {

                AddNewItem();

            }

            // 通知界面数据源已更新
            OnPropertyChanged(nameof(Items));
        }

        // 数据源的公共属性


        // 是否正在刷新的属性,并使用 SetProperty 方法实现属性更改通知
        public bool IsRefreshing
        {
            get => _isRefreshing;
            set => SetProperty(ref _isRefreshing, value);
        }

    

        // 刷新命令,绑定到下拉刷新控件
        public Command RefreshCommand => new Command(async () => await OnRefresh());

        // 下拉刷新事件处理方法
        private async Task OnRefresh()
        {
            // 开始刷新
            IsRefreshing = true;

            // 模拟异步操作(例如,从网络加载数据)
            await Task.Delay(2000);

            // 在主线程上更新 UI
            await MainThread.InvokeOnMainThreadAsync(() =>
            {
                // 添加新的列表项
                for (int i = 0; i < 10; i++)
                {
                    AddNewItem();
                }

                // 结束刷新
                IsRefreshing = false;
            });
        }

        // 列表项即将可见事件处理方法
        private async void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
        {
            // 检查是否即将显示最后一个列表项,触发加载更多
            if (e.Item == _items[_items.Count - 1])
            {
                await LoadMoreItems();
            }
        }

        // 加载更多的方法
        private async Task LoadMoreItems()
        {
            // 模拟加载更多数据的异步操作
            await Task.Delay(2000);

            // 在主线程上更新 UI
            await MainThread.InvokeOnMainThreadAsync(() =>
            {
                // 添加更多新的列表项
                for (int i = 0; i < 10; i++)
                {
                    AddNewItem();
                }
                IsRefreshing = false;
            
            });
        }

        private void AddNewItem()
        {
            string randomFruit = fruits[_random.Next(fruits.Length)];

            _items.Add(new ProductItem
            {
                ImageSource = "dotnet_bot.png", // 替换为实际的图片路径
                ProductName = $"{randomFruit}: {_items.Count}",
                Price = $"价格: {_random.NextDouble() * 100:F2} 元"
            });
        }


        // 通用方法,用于设置属性并触发属性更改通知
        protected bool SetProperty<T>(ref T backingStore, T value,
            [CallerMemberName] string propertyName = "",
            Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;

            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }
    }
}
相关推荐
anlog15 分钟前
C#在自定义事件里传递数据
开发语言·c#·自定义事件
18号房客1 小时前
macOS开发环境配置与应用开发教程(一)
vscode·macos·visualstudio·eclipse·intellij-idea·phpstorm·visual studio
向宇it2 小时前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
仰望大佬0072 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
糖朝2 小时前
c#读取json
c#·json
向宇it7 小时前
【从零开始入门unity游戏开发之——C#篇26】C#面向对象动态多态——接口(Interface)、接口里氏替换原则、密封方法(`sealed` )
java·开发语言·unity·c#·游戏引擎·里氏替换原则
IT规划师9 小时前
Visual Studio - API调试与测试工具之HTTP文件
visual studio·http文件
Java Fans11 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手11 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
码农君莫笑11 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio