I tried to pass an object parameter thru ViewModel Books
to ViewModel Book Detail
. I defined both viewmodels as ObservableObject
and used a dictionary in ViewModel Books to pass parateter like below:
I expect to have Title = this.Book.Name;
to work and get the value, but the this. Book
or even Book
property alone is null, but I can get its value in Details XAML page. I need it on the DetailsViewModel constructor. What's my issue?
BooksViewModel.cs
[RelayCommand]
async Task GoToDestinationAsync(Book book)
{
await Shell.Current.GoToAsync($"{nameof(DetailsPage)}", true,
new Dictionary<string, object>
{
{"Book",book}
});
}
DetailsViewModel.cs
[QueryProperty(nameof(Book), "Book")]
public partial class BookDetailsViewModel : BaseViewModel
{
[ObservableProperty]
Book book;
public BookDetailsViewModel()
{
Title = this.Book.Name;
}
}
DetailsPage.xaml.cs
public partial class DetailsPage : ContentPage
{
public DetailsPage(MonkeyDetailsViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
}
}
AppShell.cs
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));
}
}
MauiProgram.cs
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.Services.AddSingleton<BooksViewModel>();
builder.Services.AddTransient<BookDetailsViewModel>();
builder.Services.AddSingleton<MainPage>();
builder.Services.AddTransient<DetailsPage>();
return builder. Build();
}
}
As Jason said, constructor runs first so you cannot get the Book property. I assume that you may want to set the initial value for Title property. But I think you don't have to set the value in constructor. You could just set the value in Setter method:
Also, in MAUI page has OnAppearing method, you could also set the value in OnAppearing method in code behind.
For more info, you may refer to Pass data
Hope it helps!