练习 - 将事件处理程序转换为命令

已完成

在本练习中,切换回你在上一练习中处理过的“影片列表”应用。 这一次,将“删除”菜单的事件处理程序转换为命令。

下载并运行示例

注意

如果你计划从 Windows 运行和调试 Android 上的 .NET MAUI 应用,建议将练习内容克隆或下载到较短的文件夹路径(例如 C:\dev),以避免生成进程生成的文件超过最大路径长度。

此项目显示影片列表。 单击影片可导航到详细信息页面,其中包含有关影片的详细信息。

  1. 克隆或下载练习存储库
  2. 导航到 part6-exercise2 文件夹,然后打开 MovieCatalog.sln 解决方案。
  3. 生成并运行应用程序,确保它能正常运行。 显示屏幕后,你应该会看到电影列表。 右键单击列出的某个电影,应用会导航到详细信息页面。

检查代码

打开 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);
}

添加 命令

将事件处理程序转换为命令的第一步是将命令添加到视图模型。 此命令接受影片并将其从集合中删除。

  1. 在“解决方案资源管理器”窗口中,打开 ViewModels\MovieListViewModel.cs 文件。

  2. 将以下属性添加到 MovieListViewModel 类:

    public ICommand DeleteMovieCommand { get; private set; }
    
  3. 接下来,找到 MovieListViewModel 构造函数并实例化命令:

    public MovieListViewModel()
    {
        Movies = [];
        DeleteMovieCommand = new Command<MovieViewModel>(DeleteMovie);
    }
    

    DeleteMovie 方法已存在并接受 MovieViewModel 参数。 该命令包装该方法并将其公开在视图模型上。

  4. 打开 ViewModels\MoviesListPage.xaml 文件。

  5. 更新 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

  6. 打开视图的代码隐藏文件 Views\MoviesListPage.xaml.cs,并删除 MenuItem_Clicked 代码。

  7. 运行应用,然后右键单击或长按其中一个电影。 从上下文菜单中选择“删除”。 影片将从列表中删除。