You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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>

错误分析

  1. Appearing命令未触发加载动作:XAML中绑定的AppearingCommand对应ViewModel里用[RelayCommand]生成的命令,但你的Appearing方法只是重新创建了LoadPostsCommand,没有执行实际的加载逻辑。
  2. 命令逻辑冗余:重新创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:07:01