Search code examples
c#.netmauimaui-community-toolkit

What is wrong with my RelayCommand? Data loads on button press but won't load on page appearing 🫤


I'm learning C# and .NET Maui, and have run into another problem that I can't wrap my head around.

I have some data loading in from a website api, but I can only seem to get it to load into a ListView after pressing a button and can't get it to do so on loading the page. I'm hoping someone can see my problem and point me in the right direction.

First, here is the relevant part of my ViewModel.:

    public ICommand LoadPostsCommand { get; set; }

    public PostsViewModel() 
    {
        LoadPostsCommand = new Command(async () => await LoadPosts());
    }

    [RelayCommand]
    void Appearing()
    {
        LoadPostsCommand = new Command(async () => await LoadPosts());
    }

here is my code behind:

using App.ViewModels;

namespace App.Views;
public partial class HomePage : ContentPage
{
    public HomePage()
    {
        InitializeComponent();
        BindingContext = new PostsViewModel();
    }
}

and my page 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>

When I press the button, the content loads into the ListView - but it doesn't load into the page on appearing. What am I missing here? Thank you!!


Solution

  • you don't need an Appearing command, you just need the page to call the LoadPosts method in it's OnAppearing

    PostsViewModel vm;
    
    public HomePage()
    {
        InitializeComponent();
        BindingContext = vm = new PostsViewModel();
    }
    
    public async override void OnAppearing()
    {
        await vm.LoadPosts();
    }