Tanaka Mawere
Tanaka Mawere

Reputation: 891

Run method in viewmodel after receiving object in AppShell .NET MAUI

I am sending a Course object from DashboardViewModel as shown below

DashboardViewModel.cs


        [RelayCommand]
        async void GoToCourse(Course course)
        {
            if (course == null) return;

            await Shell.Current.GoToAsync(nameof(TopicSelectionPage), true, new Dictionary<string, object> 
            {
                {"courseSelected", course}
            });
        }

to TopicSelectionViewModel which is attached below

TopicSelectionViewModel.cs

[INotifyPropertyChanged]
    [QueryProperty(nameof(CourseSelected), "courseSelected")]
    public partial class TopicSelectionViewModel
    {
        CancellationTokenSource cancellationTokenSource = new();
        [ObservableProperty]
        private Course courseSelected;
        public ObservableRangeCollection<Topic> Topics { get; set; } = new();

        [ObservableProperty]
        private bool isBusy;
        [ObservableProperty]
        private string title;
        [ObservableProperty]
        private string imageURL;


        [RelayCommand]
        async Task Refresh()
        {
            Topics.Clear();

            IsBusy = true;

            try
            {
                if (courseSelected is not null)
                {
                    Title= courseSelected.Title;
                    ImageURL = courseSelected.ImageURL;

                    if (courseSelected.CourseRef.Equals("anat1"))
                    {
                        foreach (Topic item in Constants.GetAnatomyTopics)
                        {
                            Topics.Add(item);
                        }
                    }
                    else if (courseSelected.CourseRef.Equals("phys1"))
                    {
                        foreach (Topic item in Constants.GetPhysiologyTopics)
                        {
                            Topics.Add(item);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
    }

I want to run the RefreshCommand after receiving the Course object. I tried calling the RefreshCommand in the constructor but the command is called before receiving the Course object. How do I go about this?

Upvotes: 0

Views: 992

Answers (2)

scott
scott

Reputation: 43

Another option is to create the class you are passing to your second VM as an ObservableProperty in your second VM then using OnNameOfClassBeingPassedChanged you can then call the command which will occur after the class is instantiated. No need for any xaml or OnAppearing code.

[ObservableProperty]
    Course courseSelected;
    partial void OnCourseSelectedChanged(Course value)
    {
        Refresh();
    }

Upvotes: 0

H.A.H.
H.A.H.

Reputation: 3907

How to add OnAppearing to your ViewModel:

<ContentPage.Behaviors>
    <toolkit:EventToCommandBehavior
            EventName="Appearing"
            Command="{Binding AppearingCommand}" />
</ContentPage.Behaviors>

Where toolkit is:

xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"

How to use code when assigning:

public void ApplyQueryAttributes(IDictionary<string, object> query)

When, your ViewModel is implementing:

IQueryAttributable

Edit: Instead of doing this to your ViewModel:

[INotifyPropertyChanged]
[QueryProperty(nameof(CourseSelected), "courseSelected")]

You can do this:

public partial class TopicSelectionViewModel : ObservableObject, IQueryAttributable

And then add this method:

public void ApplyQueryAttributes(IDictionary<string, object> query)

And get your data with:

query["SomeKey"]

Upvotes: 1

Related Questions