Lilly
Lilly

Reputation: 321

.NET MAUI: Passing objects from ObservableCollection to an "AddObject" page and back (MVVM)

My main page has an ObservableCollection (defined in a ViewModel) holding objects (defined in a Model) and I have other pages, one that shows details and one to add a new object. I use the MVVM CommunityToolkit.

I can pass one object from the collection to the details page:

[RelayCommand]
async Task GoToDetails(DailyScrum scrum)
{
    if (scrum is null)
        return;

    await Shell.Current.GoToAsync($"{nameof(View.ScrumDetailsPage)}", true,
        new Dictionary<string, object>
        {
            {"Scrum", scrum }
        });
}

However, I am not able to pass the whole collection to the "Add" page, add the new object and pass it back:

[RelayCommand]
async Task AddNewScrum(ObservableCollection<DailyScrum> scrums)
{
    if (scrums is null)
        return;

    await Shell.Current.GoToAsync($"{nameof(View.AddScrumPage)}", true,
        new Dictionary<string, object>
        {
            {"Scrums", scrums }
        });
}

How can I do this? Or is it a wrong attempt to pass around the collection? Can I write access the collection from another viewmodel?

Upvotes: 0

Views: 1670

Answers (1)

Liyun Zhang - MSFT
Liyun Zhang - MSFT

Reputation: 14244

If the ObservableCollection's size is small, you can try to use the Newtonsoft.Json package to convert it to string and then pass it. Such as:

var jsonstring = JsonConvert.SerializeObject(scrums);
Shell.Current.GoToAsync($"{nameof(View.AddScrumPage)}?param={jsonstring}");

And convert the string to ObservableCollection with the following code:

ObservableCollection<DailyScrum> data = JsonConvert.DeserializeObject<ObservableCollection<DailyScrum>>(jsonstring);

If the collection's size is big, you can store the string in the Preferences. Such as:

var jsonstring = JsonConvert.SerializeObject(scrums);
Preferences.Set("Data", jsonstring);

And get the data in the AddScrumPage:

bool hasKey = Preferences.ContainsKey("Data");
var content = Preferences.Get("Data", string.Empty);
ObservableCollection<DailyScrum> data = hasKey ? JsonConvert.DeserializeObject<Model>(content) : null;

Update

You can try to use the Shell.Current.Navigation, it has the same effect as the Shell.Current.GoToAsync, such as:

[RelayCommand]
async Task GoToDetails(DailyScrum scrum)
{
    if (scrum is null)
        return;

    await Shell.Current.Navigation.PushAsync(new View.ScrumDetailsPage(scrums))
}

Upvotes: 0

Related Questions