一个类似商品例表的下拉效果:
代码
新增个类为商品商体类
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;
}
}
}