Xamarin.forms 将对象列表作为导航参数发送

Xamarin.forms 将对象列表作为导航参数发送,xamarin.forms,prism,Xamarin.forms,Prism,我有一个应用程序,可以让人们查看有关特定电影的信息。在我的主页(流派列表页面)中,我有一个列表,可以将数据库中的每一部电影排序为一个流派列表。相同类型的电影类型和数量显示在CollectionView项目模板(GenreModel)中。当用户点击某个流派时,他们会使用另一个CollectionView(FilmListPage)导航到另一个页面。此CollectionView使用包含电影标题和分级的ItemTemplate(FilmModel)填充 当前,当用户导航到FilmListPage时,

我有一个应用程序,可以让人们查看有关特定电影的信息。在我的主页(流派列表页面)中,我有一个列表,可以将数据库中的每一部电影排序为一个流派列表。相同类型的电影类型和数量显示在CollectionView项目模板(GenreModel)中。当用户点击某个流派时,他们会使用另一个CollectionView(FilmListPage)导航到另一个页面。此CollectionView使用包含电影标题和分级的ItemTemplate(FilmModel)填充

当前,当用户导航到FilmListPage时,构造函数调用一个方法来查询数据库,检索在GenreListPage中选择的具有指定类型的所有电影

我想改变这一点,所以我已经将类型FilmModel的列表包含到我的GenreModel中。当我导航到FilmListPage时,我希望将FilmModel列表作为参数传递,并在FilmListPage中检索它。然而,根据我的理解,传递导航参数只意味着传递字符串。这是真的吗

一些代码

GenreModel.cs

public class GenreModel{

    public string GenreType {get; set;}

    public List<FilmModel> AssociatedFilms {get; set;}
}
GenreListPageViewModel.cs

public class GenreListPageViewModel.cs  : ViewModelBase
{
    private GenreModel _selectedGenre;
    private List<GenreModel> _genres;

    public GenreModel SelectedGenre 
    {
        get => _selectedGenre;
        set => SetProperty(ref _selectedGenre, value);
    }

    public List<GenreModel> Genres
    {
        get => _genres;
        set => SetProperty(ref _genres, value);
    }

    public GenreListPageViewModel(INavigationService navigationService, IDatabaseService databaseService) : base (navigationService)
    {
        Genres = new ObservableCollection<GenreModel>(databaseService.GetFilms());
    }

    public async void ItemSelected()
    {
        var p = new NavigationParameters;
        p.Add("Films", SelectedGenre.AssociatedFilms);
        p.Add("Genre", SelectedGenre.GenreType);
        await NavigationService.NavigateAsync("FilmListPage", p);
    }
}

public class FilmListPageViewModel.cs : ViewModelBase, INavigationAware
{
    IDatabaseService _databaseService;

    private string _genre;
    private List<FilmModel> _films = new List<FilmModel>();

    public string Genre
    {
        get => _genre;
        set => SetProperty(ref _genre, value);
    }

    public List<FilmModel> Films
    {
        get => _films;
        set => SetProperty(ref _films, value);
    }

    public GenreListPageViewModel(INavigationService navigationService, IDatabaseService databaseService) : base (navigationService)
    {
        _databaseService = databaseService;
    }

    public void OnNavigatedFrom(INavigationParameters parameters)
    {

    }

    public void OnNavigatedTo(INavigationParameters parameters)
    {
        Genre = parameters.GetValue<string>("Genre")};

        //old code that used to get film by selected genre
        //Films = databaseService.GetFilmsByGenre(Genre);

        Films = new ObservableCollection<FilmModel>(parameters.GetValues<FilmModel>("Films"));
    }
}

公共类GenreListPageViewModel.cs:ViewModelBase
{
私人GenreModel_selectedGenre;
私人列表(流派),;
公共GenreModel SelectedGenre
{
get=>(u selectedGenre ;;
set=>SetProperty(ref\u selectedGenre,value);
}
公开列表体裁
{
获取=>\u类型;
set=>SetProperty(参考类型,值);
}
public GeneRelistPageViewModel(INavigationService navigationService,IDatabaseService databaseService):基础(navigationService)
{
Genres=新的observeCollection(databaseService.GetFilms());
}
公共异步void ItemSelected()
{
var p=新的导航参数;
p、 添加(“影片”,选择相关影片);
p、 添加(“流派”,选择Genre.GenreType);
等待NavigationService.NavigateAsync(“FilmListPage”,p);
}
}
FilmListPageViewModel.cs

public class GenreListPageViewModel.cs  : ViewModelBase
{
    private GenreModel _selectedGenre;
    private List<GenreModel> _genres;

    public GenreModel SelectedGenre 
    {
        get => _selectedGenre;
        set => SetProperty(ref _selectedGenre, value);
    }

    public List<GenreModel> Genres
    {
        get => _genres;
        set => SetProperty(ref _genres, value);
    }

    public GenreListPageViewModel(INavigationService navigationService, IDatabaseService databaseService) : base (navigationService)
    {
        Genres = new ObservableCollection<GenreModel>(databaseService.GetFilms());
    }

    public async void ItemSelected()
    {
        var p = new NavigationParameters;
        p.Add("Films", SelectedGenre.AssociatedFilms);
        p.Add("Genre", SelectedGenre.GenreType);
        await NavigationService.NavigateAsync("FilmListPage", p);
    }
}

public class FilmListPageViewModel.cs : ViewModelBase, INavigationAware
{
    IDatabaseService _databaseService;

    private string _genre;
    private List<FilmModel> _films = new List<FilmModel>();

    public string Genre
    {
        get => _genre;
        set => SetProperty(ref _genre, value);
    }

    public List<FilmModel> Films
    {
        get => _films;
        set => SetProperty(ref _films, value);
    }

    public GenreListPageViewModel(INavigationService navigationService, IDatabaseService databaseService) : base (navigationService)
    {
        _databaseService = databaseService;
    }

    public void OnNavigatedFrom(INavigationParameters parameters)
    {

    }

    public void OnNavigatedTo(INavigationParameters parameters)
    {
        Genre = parameters.GetValue<string>("Genre")};

        //old code that used to get film by selected genre
        //Films = databaseService.GetFilmsByGenre(Genre);

        Films = new ObservableCollection<FilmModel>(parameters.GetValues<FilmModel>("Films"));
    }
}

public class FilmListPageViewModel.cs:ViewModelBase,INavigationAware
{
IDatabaseService\u数据库服务;
私人弦乐体裁;
私有列表_films=新列表();
公共弦乐体裁
{
get=>\u体裁;
set=>SetProperty(参考类型,值);
}
公开上榜影片
{
获取=>\u电影;
set=>SetProperty(参考值);
}
public GeneRelistPageViewModel(INavigationService navigationService,IDatabaseService databaseService):基础(navigationService)
{
_databaseService=数据库服务;
}
OnNavigatedFrom上的公共void(INavigationParameters)
{
}
导航到上的公共void(INavigationParameters)
{
Genre=parameters.GetValue(“Genre”)};
//用于按选定类型获取电影的旧代码
//电影=数据库服务。GetFilmsByGenre(类型);
Films=新的可观察采集(parameters.GetValues(“Films”);
}
}
然而,根据我的理解,传递导航参数只意味着传递字符串。这是真的吗

幸运的是,没有,与键关联的值可以是任何值(请查看):

公共接口INavigationParameters:IEnumerable

导航和对话框参数实际上都是
IEnumerable
。这对你来说意味着什么

首先,这意味着任何给定的键都可能包含一对多的实际值

navigationParameters.Add(“消息”,“Prism非常适合Wpf应用程序”);
navigationParameters.Add(“message”,“Prism非常适合Xamarin.Forms应用程序”);
navigationParameters.Add(“消息”,“Prism非常适合Uno和WinUI应用程序”);
第二,这意味着你可以传递任何你想要的参数

var messages=new[]{
“Prism非常适合Wpf应用程序”,
“Prism非常适合Xamarin.Forms应用程序”,
“Prism非常适合Uno和WinUI应用程序”
};
导航参数。添加(“消息”,消息);
正如您可能熟悉的那样,您可以将参数调出,如:

var messages=navigationParameters.Get(“消息”);
如果使用第一种添加消息的方法使用此方法,则可能会出现异常,因为它会命中第一个值并看到它不是同一类型。如果您以第二种方式添加它,这仍然有效,因为您添加了一个
IEnumerable

然而,还有第二种方法非常适合你所寻找的,无论你的价值是如何增加的,它都会起作用

var messages=navigationParameters.GetValues(“消息”);

方法返回给定泛型类型的IEnumerable

哦,我明白了。所以如果我想返回我的列表,我会在标记中使用列表对象类型?比如
navigationParameters.GetValues(“电影”)