The issue that I am having is that when I navigate to the EditTermPage, the title and date fields are not showing the object fields that I am passing over. I believe the object is passed to the EditTermViewModel, but it doesn't seem like it is assigning it the the term Observable property. When I do a breakpoint on the Edit button the term field is populated with the correct information, it just isn't sending it over to the other view model.
Main view:
<CollectionView ItemsSource="{Binding Terms}"
BackgroundColor="LightGray">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="Model:TermModel">
<Border StrokeThickness="0" Padding="20,10,20,0">
<Border.Shadow>
<Shadow Brush="Black"
Opacity="0.5"
Radius="10"
Offset="5,5"/>
</Border.Shadow>
<VerticalStackLayout Padding="20"
Margin="0,5,0,20"
BackgroundColor="Aqua">
<Grid ColumnDefinitions="Auto, *, Auto">
<Label Text="{Binding Title}"
x:Name="TermTitle"
Grid.Column="0"
FontAttributes="Bold"
FontSize="Large"/>
<Button Text="Edit"
Grid.Column="2"
Command="{Binding Source={RelativeSource AncestorType= {x:Type ContentPage}}, Path=BindingContext.EditTermCommand}"
CommandParameter="{Binding .}"/>
</Grid>
<HorizontalStackLayout>
<Label Text="{Binding TermStartDate, StringFormat='{0:MM/dd/yyyy}'}"
x:Name="StartDate"/>
<Label Text=" - "/>
<Label Text="{Binding TermEndDate, StringFormat='{0:MM/dd/yyyy}'}"
x:Name="EndDate"/>
</HorizontalStackLayout>
<Button Text="Select"
WidthRequest="100"
Margin="0,30,0,0"
x:DataType="ViewModel:TermViewModel"
BindingContext="{ViewModel:TermViewModel}"
Command="{Binding SelectTermCommand}"/>
</VerticalStackLayout>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Main view model:
public partial class TermViewModel : BaseViewModel
{
[ObservableProperty]
public ObservableCollection<TermModel> _terms = new();
private readonly IDatabase<TermModel> _database;
[ObservableProperty]
private TermModel _selectedTerm;
public TermViewModel()
{
_database = new DatabaseService<TermModel>();
LoadTerms();
}
public async Task LoadTerms()
{
IsBusy = true;
try
{
this._terms.Clear();
var terms = await _database.GetItemsAsync();
foreach (var term in terms)
{
this._terms.Add(term);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
throw;
}
finally
{
IsBusy = false;
}
}
// Button Commands
[RelayCommand]
private async Task EditTerm(TermModel term)
{
if (term == null)
return;
await Shell.Current.GoToAsync(nameof(EditTermPage), true, new Dictionary<string, object>
{
{ nameof(TermModel), term }
});
}
}
EditTermPage:
<VerticalStackLayout HorizontalOptions="Center">
<Label Text="Term Details"
VerticalOptions="Center"
HorizontalOptions="Center"
Padding="20"
FontSize="Large"/>
<Grid RowDefinitions="*, *, *"
ColumnDefinitions="*, *">
<Label Grid.Row="0"
Grid.Column="0"
Text="Name"
VerticalOptions="Center"/>
<Entry Grid.Row="0"
Grid.Column="1"
MaximumWidthRequest="300"
Text="{Binding Term.Title, Mode=TwoWay}" />
<Label Grid.Row="1"
Grid.Column="0"
Text="Start Date"
VerticalOptions="Center"/>
<DatePicker Grid.Row="1"
Grid.Column="1"
Date="{Binding Term.TermStartDate, Mode=TwoWay}"/>
<Label Grid.Row="2"
Grid.Column="0"
Text="End Date"
VerticalOptions="Center"/>
<DatePicker Grid.Row="2"
Grid.Column="1"
Date="{Binding Term.TermEndDate, Mode=TwoWay}"/>
</Grid>
</VerticalStackLayout>
EditTermViewModel:
[QueryProperty(nameof(TermModel), "Term")]
public partial class EditTermViewModel : BaseViewModel
{
[ObservableProperty]
private TermModel term;
public EditTermViewModel()
{
}
}
Termsproperty throughItemsSource="{Binding Terms}"whileTermViewModelhas a private_termsfield, not aTermsproperty. Same withEditTermPage. This is incomplete code at best[QueryProperty(nameof(TermModel), "Term")]is one the few things that caused me more trouble, that was just not worth the time saved for implementing a single method. Not saying that there is anything wrong with it in particular. And you can definitely still diagnose your problem using it. But I prefer the alternative.