.NET Maui中RelayCommand问题:页面加载时数据无法自动加载
.NET Maui页面加载时无法自动从API加载数据至ListView
我正在学习C#和.NET Maui,遇到一个问题:点击按钮能成功从网站API加载数据到ListView,但页面加载完成显示时无法自动加载。
相关代码
ViewModel部分
public ICommand LoadPostsCommand { get; set; } public PostsViewModel() { LoadPostsCommand = new Command(async () => await LoadPosts()); } [RelayCommand] void Appearing() { LoadPostsCommand = new Command(async () => await LoadPosts()); }
页面后台代码
using App.ViewModels; namespace App.Views; public partial class HomePage : ContentPage { public HomePage() { InitializeComponent(); BindingContext = new PostsViewModel(); } }
页面XAML
<?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" x:Class="App.Views.HomePage" Title="Posts" xmlns:local="clr-namespace:App" xmlns:vm="clr-namespace:App.ViewModels" x:DataType="vm:PostsViewModel" xmlns:mct="clr-namespace:CommunityToolkit.Maui.Behaviors;assembly=CommunityToolkit.Maui" > <ContentPage.Behaviors> <mct:EventToCommandBehavior Command="{Binding AppearingCommand}" EventName="Appearing" /> <mct:EventToCommandBehavior Command="{Binding DisappearingCommand}" EventName="Disappearing" /> </ContentPage.Behaviors> <ListView ItemsSource="{Binding Data.Posts}" SeparatorVisibility="None"> <ListView.Header> <VerticalStackLayout Spacing="25" Padding="30,0" VerticalOptions="Center"> <Button x:Name="UpdateBtn" Text="Load Posts" Command="{Binding LoadPostsCommand}" Margin="10" /> </VerticalStackLayout> </ListView.Header> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid Padding="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Image Grid.RowSpan="2" Source="{Binding Image.ImageUrl}" Aspect="AspectFill" HeightRequest="60" WidthRequest="60" /> <Label Grid.Column="1" Text="{Binding Title}" FontAttributes="Bold" /> <Label Grid.Row="1" Grid.Column="1" Text="{Binding Body}" FontAttributes="None" Margin="5" VerticalOptions="End" /> <Label Grid.Row="2" Grid.Column="1" Text="{Binding Username}" FontAttributes="None" Margin="5" VerticalOptions="End" /> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </ContentPage>
错误分析
- Appearing命令未触发加载动作:XAML中绑定的
AppearingCommand对应ViewModel里用[RelayCommand]生成的命令,但你的Appearing方法只是重新创建了LoadPostsCommand,没有执行实际的加载逻辑。 - 命令逻辑冗余:重新创建
LoadPostsCommand完全没必要,因为构造函数里已经初始化过这个命令。
修复方案
方案1:在Appearing命令中直接调用加载方法
修改ViewModel的Appearing方法,直接执行LoadPosts():
public ICommand LoadPostsCommand { get; set; } public PostsViewModel() { LoadPostsCommand = new Command(async () => await LoadPosts()); } [RelayCommand] async Task Appearing() { await LoadPosts(); // 直接触发加载 }
方案2:在ViewModel构造函数中自动加载
如果希望页面初始化时就加载数据,可直接在构造函数中调用加载方法:
public PostsViewModel() { LoadPostsCommand = new Command(async () => await LoadPosts()); _ = LoadPosts(); // 构造函数中异步加载(避免阻塞UI) }
方案3:执行已有的LoadPostsCommand
若想通过现有命令触发,可在Appearing方法中执行命令:
[RelayCommand] void Appearing() { LoadPostsCommand.Execute(null); // 调用已初始化的加载命令 }
额外检查项
- 确保
Data.Posts是ObservableCollection<T>类型,这样数据更新时UI才能自动刷新。 - 确认
LoadPosts()方法中正确处理了API请求和数据赋值,没有空引用或异常被吞掉。
内容的提问来源于stack exchange,提问作者ReticentRobot
相关产品推荐
相关产品推荐

