I am new to .Net Maui. I have follow James Montemagno's video tuorial:
https://www.youtube.com/watch?v=ddmZ6k1GIkM&list=PLdo4fOcmZ0oUBAdL2NwBpDs32zwGqb9DY&index=6 on navigating between pages. I can successfully navigate from one page to the next and also send a complex data object as a parameter. However, on the new page, I want to use the parameter to fetch objects via a webservice in my ViewModel, and bind the xaml to the newly fetched objects.
At first I tried this in the ViewModels' constructor, but the parameters where still null inside the constructor. I then invoked an event that fired when the property I am binding to changes partial void OnLoginResultChanged(LoginResult value)
. From there I call an async Task to fetch the objects from the webservice and try and bind and display them in the xaml. Unfortunately, I am not getting anything to show in the xaml.
Here is my code: ViewModel:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MealPacApp.Model;
namespace MealPacApp.ViewModel
{
[QueryProperty(nameof(Model.LoginResult), "LoginResult")]
public partial class MainViewModel : ObservableObject
{
IConnectivity connectivity;
Services.MealPacService mealPacService;
[ObservableProperty]
Model.User user = new();
[ObservableProperty]
Model.LoginResult loginResult;
partial void OnLoginResultChanged(LoginResult value)
{
this.GetDataForViewCommand.ExecuteAsync(null);
}
public MainViewModel(IConnectivity connectivity, Services.MealPacService mealPacService)
{
this.connectivity = connectivity;
this.mealPacService = mealPacService;
//Now check to see if there is internet connectivity
if (connectivity.NetworkAccess != NetworkAccess.Internet)
{
Shell.Current.DisplayAlert("Oops!", "No internet is available. Please ensure you have an internet connection before continuing.", "OK");
return;
}
}
[RelayCommand]
async Task GetDataForView()
{
try
{
if (loginResult != null)
{
//Its not empty, so login here
var incmoingUser = await Services.MealPacService.GetUser(loginResult.Reference, loginResult.OrganisationId);
if (incmoingUser != null)
{
user = incmoingUser;
}
}
}
catch (Exception)
{
throw;
}
}
}
}
Here is the View (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="MealPacApp.MainPage"
Title="Home"
xmlns:viewmodel="clr-namespace:MealPacApp.ViewModel"
xmlns:model="clr-namespace:MealPacApp.Model"
x:DataType="viewmodel:MainViewModel">
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label
Text="{Binding User.Name}"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Here is the Model I am trying to bind too:
namespace MealPacApp.Model
{
public partial class User
{
public int Userid { get; set; }
public string Reference { get; set; }
public string Name { get; set; }
}
}
Here is my page code behind:
using MealPacApp.ViewModel;
namespace MealPacApp
{
public partial class MainPage : ContentPage
{
public MainPage(MainViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
}
As mentioned, the navigation is working, I am just missing how to get the property change to reflect in the Xaml. I have kept the [ObservableProperty]
instead of implementing INotifyPropertyChanged
as to my understanding, it takes care of the boiler plate stuff.
Thanks in advance.
CodePudding user response:
This line
user = incmoingUser;
Is updating the private field user
You want to update the public property User
which is observable
User = incmoingUser;