I can't pass an ObservableCollection<Video> from one page to another. I use this same pattern all over my project, so I'm not sure why it's failing here. I'm using the MVVM pattern.
Here's my code:
On the "throw" side
I declare the ObservableCollection<Video> and instantiate it in the constructor:
[ObservableProperty]
private ObservableCollection<Video> videoList;
//...
public Constructor()
{
VideoList = new ObservableCollection<Video>();
}
The method that sets up the pass:
[RelayCommand]
private async Task CreateCase()
{
if (0 == VideoList.Count)
{
await App.Current.MainPage.DisplayAlert("No video(s) selected", "You must have at least one video selected to add to your new Case.", "", "OK");
return;
}
Dictionary<string, object> param = new Dictionary<string, object>
{
{ "VideoList", VideoList }
};
await Shell.Current.GoToAsync($"//{nameof(CreateCasePage)}", param);
}
The ObservableCollection<Video> makes it into this method and into the Dictionary. Here's a screenshot just to confirm. In the code, I chose three objects, and lo and behold they are in the list:

On the "Catch" side
The ObservableCollection<Video> is declared, and the QueryProperty is used. The same name is used on both the 'throw' page and 'catch' page:
[QueryProperty("VideoList", "VideoList")]
public partial class CreateCasePageViewModel : ObservableObject
{
#region Properties
[ObservableProperty]
private ObservableCollection<Video> videoList;
//...
public Constructor()
{
VideoList = new ObservableCollection<Video>();
}
}
I'm not sure if I should 'new' the ObservableCollection<Video> on the 'catch' side, but I've tried newing and and not newing it and have the same results.
Results
The ObservableCollection<Video> is always null on the 'catch' side, regardless of what I try. The thing is, I use this same code elsewhere in my project and it works.
I'm not sure what else to look at to debug.
EDIT: Using ApplyQueryAttributes but not working
I was advised to use the ApplyQueryAttributes interface, and this has gotten me closer, but it's not quite working.
My "throw" side code is the same, that is, I simply pass the ObservableObject<object> to the "catch" side with a dictionary:
[RelayCommand]
private async Task CreateCase()
{
Dictionary<string, object> param = new()
{
{ "VideoList", VideoList }
};
await Shell.Current.GoToAsync($"//{nameof(CreateCasePage)}", param);
}
On the 'catch' side, I add the IQueryAttributable interface:
public partial class CreateCasePageViewModel : ObservableObject, IQueryAttributable
{
[ObservableProperty]
private ObservableCollection<Video> videoList;
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
VideoList = query["VideoList"] as ObservableCollection<Video>;
}
}
This almost works. When I put a breakpoint inside the interface, VideoList is populated, and looks good.

However, when I attempt to access VideoList elsewhere in the ViewModel, I get an exception:
This is confounding.

You're mixing the string-based query parameters and object-based navigation data approaches here. You can check the documentation for more information.
Your receiving ViewModel should implement the IQueryAttributable interface instead of using a QueryProperty:
This is necessary, because only simple types and strings can be passed as string-based query parameters.