The Problem
I have an object that I'm passing from ViewModel A to ViewModel B. The object has properties that are used in the XAML. The problem is that I don't have access to the passed object until after the XAML runs.
Here's what I'd like to happen:

My Current Code
Here's my ViewModel. Note the Appearing method is is an EventToCommandBehavior method and runs before the XAML runs. Also note that if I put the code that's in Appearing into the ViewModel's constructor I get the same behavior: if I put a break point on the first line of the Appearing method, Object.FirstName is null.
[QueryProperty("Object","Object")]
public partial class ViewModel: ObservableObject
{
[ObservableProperty] private Object object;
[ObservableProperty] private string firstName;
[ObservableProperty] private string lastName;
[ObservableProperty] private string someOtherString;
[RelayCommand]
private async Task Appearing()
{
FirstName = Object.FirstName;
LastName = Object.LastNamel
SomeOtherString = Object.SomeOtherString;
}
// NOTE: WE COULD USE THE CONSTRUCTOR INSTEAD OF 'APPEARING' AND
// GET THE SAME RESULTS
//public ViewModel()
//{
// FirstName = Object.FirstName;
// LastName = Object.LastNamel
// SomeOtherString = Object.SomeOtherString;
//}
Here's the XAML that DOESN'T get populated:
<ContentPage>
<ContentPage.Behaviors>
<toolkit:EventToCommandBehavior Command="{Binding AppearingCommand}"
EventName="Appearing" />
<Grid>
<Label Text="{Binding FirstName}"/>
<Label Text="{Binding LastName}"/>
<Label Text="{Binding SomeOtherString}"/>
</Grid>
</ContentPage>
The Object is passed correctly
I do eventually get access to the passed object. For example, if I do this the labels get populated, but it's too little too late. If I put a break point over the first line in TooLittleTooLate(), the Object.FirstNAme is populated with the passed value.
[QueryProperty("Object","Object")]
public partial class ViewModel: ObservableObject
{
[ObservableProperty] private Object object;
[ObservableProperty] private string firstName;
[ObservableProperty] private string lastName;
[ObservableProperty] private string someOtherString;
[RelayCommand]
private async TooLittleTooLate()
{
FirstName = Object.FirstName;
LastName = Object.LastNamel
SomeOtherString = Object.SomeOtherString;
}
}
Along with this xaml:
<ContentPage>
<Grid>
<Label Text="{Binding FirstName}"/>
<Label Text="{Binding LastName}"/>
<Label Text="{Binding SomeOtherString}"/>
<Button Text="Press Me"
Command={Binding TooLittleTooLateCommand}/>
</Grid>
</ContentPage>
When I do this and the user presses the button, the labels get populated, but that's too late! I need the labels to be populated before the XAML runs for the first time.
I think I'm missing something really obvious, because I've done stuff like this before with no issues.
EDIT: Solution
Yep, the problem was obvious. Instead of binding to the property, I should have bound to the Object.Property.
Instead of this:
Label Text={Binding FirstName}/>
It should've been this:
Label Text={Binding Object.FirstName}/>
I'm not feeling too intelligent right now.
Just as Jason said that You should be able to bind directly to Object and when Object is set it will fire a PropertyChanged and update the UI.
Here is the code you can refer to: