【问题标题】:How to pass QUERYPARAMETER to ViewModel constructor?如何将 QUERYPARAMETER 传递给 ViewModel 构造函数?
【发布时间】:2022-09-28 18:40:12
【问题描述】:

我正在学习如何在使用 AppShell 将数据从一个视图模型传递到下一页视图模型以及使用 CommunityToolkit.Mvvm 的 maui 应用程序上使用。但我不知道如何将返回查询参数传递给下一页 viewmodel 方法。

下一页的视图模型

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using TimesNewsApp.Models;
using TimesNewsApp.Services;

namespace TimesNewsApp.ViewModels
{
    [QueryProperty(nameof(SelectedGenre), nameof(SelectedGenre))]
    public partial class MovieListGenrePageViewModel : BaseViewModel
    {
        public ObservableCollection<Result> Movie { get;} = new();

        [ObservableProperty]
        private Genre selectedGenre;
        NewsApiManager apiService;

        public Command GetMovieComand { get; }

        public MovieListGenrePageViewModel(NewsApiManager apiService)
        {
            this.apiService = apiService;
            Task.Run(async () => await GetMovies(SelectedGenre));
        }


        async Task GetMovies(Genre SelectedGenre)
        {
            if (IsBusy)
                return;

            try
            {
                IsBusy = true;
                if (SelectedGenre == null)
                    return;
                
                Movie movies = await apiService.GetMovieByGenre(SelectedGenre.Id);
                if (Movie.Count != 0)
                    return;
                foreach (var item in movies.results)
                    Movie.Add(item);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($\"Unable to get movie: {ex.Message}\");
                await Application.Current.MainPage.DisplayAlert(\"Error!\", ex.Message, \"OK\");
            }
            finally
            {
                IsBusy = false;
            }
        }
    }
}


我尝试在构造函数中使用它;

public MovieListGenrePageViewModel(NewsApiManager apiService){
        ...
this.SelectedGenre = SelectedGenre;
Task.Run(async () => await GetMovies(SelectedGenre));
}

但 SelectedGenre 返回 null。请问如何将 Object SelectedGenre 设置为 GetMovie 方法?

    标签: c# mvvm maui


    【解决方案1】:

    如果要将参数传递到下一页,可以使用 Shell。您可以将数据放入字典中并将其传递到下一页。

      async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
            var navigationParameter = new Dictionary<string, object>
            {
                { "Bear", animal }
            };
            await Shell.Current.GoToAsync($"nextpage", navigationParameter);
        }
    

    在下一页中,可以通过使用QueryPropertyAttribute 为每个基于字符串的查询参数和基于对象的导航参数装饰接收类来接收导航数据。QueryPropertyAttribute 的第一个参数指定将要接收的属性的名称接收数据,第二个参数指定参数 id。

    [QueryProperty(nameof(Bear), "Bear")]
    public partial class BearDetailPage : ContentPage
    {
        Animal bear;
        public Animal Bear
        {
            get => bear;
            set
            {
                bear = value;
                OnPropertyChanged();
            }
        }
    
        public BearDetailPage()
        {
            InitializeComponent();
            BindingContext = this;
        }
    }
    

    更多详情可以参考:https://docs.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation#pass-data

    【讨论】:

      【解决方案2】:

      您不能,因为在将 QueryParameter 传递给 ViewModel 之前调用了构造函数。

      但是,您有很多方法可以实现您的目标。 一种方法是设置页面的 Appearing 方法并调用 ViewModel 的函数。

      在您的 xaml 页面集中

      Appearing="Page_Appearing"

      然后在您的页面 .cs 文件集中并确保您的 ViewModel 可访问。 (例如,在 XAML 中定义或使用定位器/容器服务)

          public AddProjectPage()
          {
              InitializeComponent();
              this.BindingContext = ViewModel;
          }
      
          private async void Page_Appearing(object sender, EventArgs e)
          {
              base.OnAppearing();
      
      
              await this.ViewModel.InitAsync(); //  
      
          }
      

      在您的 ViewModel 中定义一个名为 InitAsync 的函数来完成所有初始化工作。

      【讨论】:

        猜你喜欢
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多