练习 - 使用 ViewModel 管理选择
在我们的练习中,暂时不考虑人力资源应用的例子。 我们将使用可以列出影片的应用程序。 该应用已具有两个页面和带有一些基本绑定内容的 ViewModel。 两个页面分别是列表页面和详细信息页面。 我们将修改选择逻辑,让 ListView
和详细信息页面使用相同的 ViewModel 属性。
本模块使用 .NET 9.0 SDK。 通过在首选命令终端中运行以下命令,确保你已安装 .NET 9.0:
dotnet --list-sdks
将显示类似于以下示例的输出:
8.0.100 [C:\Program Files\dotnet\sdk]
9.0.100 [C:\Program Files\dotnet\sdk]
确保列出了以 9
开头的版本。 如果未列出任何版本或未找到命令,请安装最新的 .NET 9.0 SDK。
打开初学者解决方案
- 克隆或下载练习存储库。
- 导航到 part4-exercise1 文件夹,然后打开 MovieCatalog.sln 解决方案。
- 生成并运行应用程序,确保它能正常运行。 应该会看到屏幕上显示了电影列表。 选择列表中的某部影片,应用就会导航到详细信息页面。
检查代码
花几分钟时间检查视图模型和视图的结构。 如果你熟悉 Extensible Application Markup Language (XAML) 和数据绑定,那这应该看起来都很熟悉,但结构使用 Model-View-ViewModel (MVVM) 模式。
此处有一个 MovieListViewModel
,它有双重作用,一是作为应用的整体 ViewModel,二是作为 MoviesListPage
的 ViewModel。 此 viewmodel 包含从模型加载的影片列表,它是项目中包含的 json 文件。 另一个 viewmodel 是 MovieViewModel
,表示一部影片。 它同样具有双重作用:为列表页面中的行提供数据,以及作为 MovieDetailPage
的 BindingContext
。
添加选择支持
MoviesListPage
是应用运行时显示的第一个页面。 页面上的 ListView
会绑定到由整个 viewmodel MovieListViewModel
提供的 MovieViewModel
实例的集合。 在视图中选择某个影片时,ItemTapped
事件将导航到 MovieDetailPage
,以将项(即影片)的 BindingContext
传递给视图的构造函数。 MovieDetailPage
设置作为页面的 BindingContext
传递的 viewmodel。
而是让我们更新应用,以让 MovieDetailPage
从整个应用的 viewmodel 中读取所选影片。
在“解决方案资源管理器”窗口中,打开 ViewModels\MovieListViewModel.cs 文件。
将以下代码添加到
MovieListViewModel
类:private MovieViewModel _selectedMovie; public MovieViewModel SelectedMovie { get => _selectedMovie; set => SetProperty(ref _selectedMovie, value); }
接下来,打开 Views\MoviesListPage.xaml 文件。
找到
ListView
元素,并添加SelectedItem
属性:<ListView ItemsSource="{Binding Movies}" SelectedItem="{Binding SelectedMovie, Mode=OneWayToSource}" Margin ... >
此属性将列表的选定项绑定到 viewmodel 中的新属性。
打开视图的代码隐藏文件 Views\MoviesListPage.xaml.cs。
将
ListView_ItemTapped
事件处理程序代码替换为以下代码:private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e) { await Navigation.PushAsync(new Views.MovieDetailPage()); }
新
MovieDetailPage
构造函数不再接受构造函数中的影片,而是会读取应用的主 viewmodel。打开 Views\MovieDetailPage.xaml.cs 文件,并将构造函数更改为以下代码:
public MovieDetailPage() { BindingContext = App.MainViewModel.SelectedMovie; InitializeComponent(); }
此代码将视图的绑定上下文设置为所选影片。
运行应用并验证代码是否会按预期工作。