Todd T
Todd T

Reputation: 335

.Net Maui MVVM - What is the best approach to populating a CollectionView upon a Page/View opening?

I'm new to .Net Maui but have completed James Montemagno's 4 hour Workshop. Included in the Workshop was:

  1. Creating a Page with a CollectionView
  2. Creating a ViewModel
  3. Creating an async method which calls a data service to retrieve data
  4. Configuring the async method as a ICommand
  5. Binding the data model list to the CollectionView
  6. Binding the Command to a Button

Clicking the button works and populates the CollectionView. How would I go about removing the button and performing this action when the page opens? Note I tried modifying the method by removing the "[ICommand]" which did not work. Also, should this action be done in the Code Behind or in the ViewModel?

Thanks in advance for assistance!

(ModelView)

public partial class FieldAssignedWbsViewModel : BaseViewModel

{
FieldAssignedWbsService fieldAssignedWbsService;
public ObservableCollection<FieldAssignedWbs> WbsList { get; set; } = new();

public FieldAssignedWbsViewModel(FieldAssignedWbsService fieldAssignedWbsService)
{
    Title = "Wbs Assigned";
    this.fieldAssignedWbsService = fieldAssignedWbsService;
}

[ICommand]
async Task GetFieldAssignedWbsListAsync()
{
    if (IsBusy)
        return;
    try
    {
        IsBusy = true;

        var wbsList = await fieldAssignedWbsService.GetFieldAssignedWbsList();

        if (WbsList.Count != 0)
            WbsList.Clear();

        foreach (var wbs in wbsList)
            WbsList.Add(wbs);
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
        await Shell.Current.DisplayAlert("Error!",
            $"Undable to get monkeys: {ex.Message}", "OK");
    }
    finally
    {
        IsBusy = false;
    }
}

}

(CollectionView Binding)

<CollectionView BackgroundColor="Transparent"
                    ItemsSource="{Binding WbsList}"
                    SelectionMode="None">

(Code behind page with incorrect call to Command Method)

public partial class FieldAssignedWbsPage : ContentPage
{
public FieldAssignedWbsPage(FieldAssignedWbsViewModel viewModel)
{
    InitializeComponent();
    BindingContext = viewModel;
    //The following call does not work 
    //Hover message: Non-invocable member... cannot be called like a method
    await viewModel.GetFieldAssignedWbsListCommand();  
}
}

Upvotes: 10

Views: 10410

Answers (2)

JPA
JPA

Reputation: 352

Although the original answer is very valid, I'd recommend installing Microsoft's .NET MAUI Community Toolkit, then using its EventToCommand features.

After installing, add builder.UseMauiCommunityToolkit() to CreateMauiApp() method in MauiProgram.cs.

Then, in relevant XAML page, add this namespace xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" and then you should be able to use this block of code to do what you want:

<ContentPage.Behaviors>
    <toolkit:EventToCommandBehavior
        EventName="Appearing"
        Command="{Binding GetFieldAssignedWbsListCommand}" />
</ContentPage.Behaviors>

I believe that this is a slightly cleaner solution as it avoids populating the code-behind with any code and keeps UI handling purely between the ViewModel and the View.

Upvotes: 18

Jason
Jason

Reputation: 89082

use OnAppearing. You may also need to make the GetFieldAssignedWbsList public

protected override async void OnAppearing()
{
  await viewModel.GetFieldAssignedWbsListCommand.Execute(null);  
}

Upvotes: 3

Related Questions