练习 - 将事件处理程序转换为命令
在本练习中,切换回你在上一练习中处理过的“影片列表”应用。 这一次,将“删除”菜单的事件处理程序转换为命令。
下载并运行示例
注意
如果你计划从 Windows 运行和调试 Android 上的 .NET MAUI 应用,建议将练习内容克隆或下载到较短的文件夹路径(例如 C:\dev),以避免生成进程生成的文件超过最大路径长度。
此项目显示影片列表。 单击影片可导航到详细信息页面,其中包含有关影片的详细信息。
- 克隆或下载练习存储库。
- 导航到 part6-exercise2 文件夹,然后打开 MovieCatalog.sln 解决方案。
- 生成并运行应用程序,确保它能正常运行。 显示屏幕后,你应该会看到电影列表。 右键单击列出的某个电影,应用会导航到详细信息页面。
检查代码
打开 MovieCatalog 解决方案,然后打开 Views\MovieListPage.xaml 文件。 ListView
为绑定 Movies
集合中的每个影片提供一个项。 每个项定义用于删除影片的上下文菜单:
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}" x:DataType="vm:MovieViewModel">
<TextCell.ContextActions>
<MenuItem Text="Delete" IsDestructive="True" Clicked="MenuItem_Clicked" />
</TextCell.ContextActions>
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
单击菜单项时,将调用 MenuItem_Clicked
方法并移除电影。 菜单项的绑定上下文是当前影片,即 MovieViewModel
类。 但是用于删除影片的代码位于应用的主视图模型 MovieListViewModel
上。 事件处理程序在获取菜单项的绑定上下文并将其发送到视图模型的 DeleteMovie
方法时考虑了这一事实:
private void MenuItem_Clicked(object sender, EventArgs e)
{
MenuItem menuItem = (MenuItem)sender;
ViewModels.MovieViewModel movie = (ViewModels.MovieViewModel)menuItem.BindingContext;
App.MainViewModel.DeleteMovie(movie);
}
添加 命令
将事件处理程序转换为命令的第一步是将命令添加到视图模型。 此命令接受影片并将其从集合中删除。
在“解决方案资源管理器”窗口中,打开 ViewModels\MovieListViewModel.cs 文件。
将以下属性添加到
MovieListViewModel
类:public ICommand DeleteMovieCommand { get; private set; }
接下来,找到
MovieListViewModel
构造函数并实例化命令:public MovieListViewModel() { Movies = []; DeleteMovieCommand = new Command<MovieViewModel>(DeleteMovie); }
DeleteMovie
方法已存在并接受MovieViewModel
参数。 该命令包装该方法并将其公开在视图模型上。打开 ViewModels\MoviesListPage.xaml 文件。
更新
MenuItem
以将Command
参数绑定到DeleteMovieCommand
。 将当前绑定上下文作为CommandParameter
传递。<MenuItem Text="Delete" IsDestructive="True" Command="{Binding DeleteMovieCommand, Source={x:Static local:App.MainViewModel}}" CommandParameter="{Binding}" />
请注意,
Clicked
事件处理程序已从MenuItem
中删除。将绑定上下文的
Source
设置为应用的主视图模型,就像页面本身一样。MenuItem
的绑定上下文仍然是电影,并传递给CommandParameter
。打开视图的代码隐藏文件 Views\MoviesListPage.xaml.cs,并删除
MenuItem_Clicked
代码。运行应用,然后右键单击或长按其中一个电影。 从上下文菜单中选择“删除”。 影片将从列表中删除。