演習 - イベント ハンドラーをコマンドに変換する

完了

この演習では、前の演習で作業した "ムービー一覧" アプリに戻ります。 今回は、 Delete スワイプ アクションのイベント ハンドラーをコマンドに変換します。

サンプルのダウンロードと実行

Windows から Android で .NET MAUI アプリを実行してデバッグする場合は、ビルドによって生成されたファイルが最大パスの長さを超えないように、演習コンテンツを複製するか、 C:\dev\ などの短いフォルダー パスにダウンロードすることをお勧めします。

このプロジェクトでは、ムービーの一覧が表示されます。 ムービーをクリックすると、ムービーに関する詳細情報が表示された詳細ページに移動します。

  1. 演習リポジトリを複製またはダウンロードします。
  2. part6-exercise2 フォルダーに移動し、MovieCatalog.sln ソリューションを開きます。
  3. プロジェクトをビルドして実行し、プロジェクトが動作することを確認します。 画面が表示されると、ムービーの一覧が表示されるはずです。 一覧表示されているムービーの 1 つを左にスワイプして、削除アクションを表示します。

コードを確認する

MovieCatalog ソリューションを開き、Views\MovieListPage.xaml ファイルを開きます。 CollectionView は、バインドされた Movies コレクション内の各ムービーの項目を表示します。 各項目は、削除アクションで SwipeView を使用します。

<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="vm:MovieViewModel">
        <SwipeView>
            <SwipeView.RightItems>
                <SwipeItems>
                    <SwipeItem Text="Delete"
                              BackgroundColor="Red"
                              Clicked="MenuItem_Clicked" />
                </SwipeItems>
            </SwipeView.RightItems>
            <VerticalStackLayout Padding="10">
                <Label Text="{Binding Title}" 
                       FontSize="16" />
            </VerticalStackLayout>
        </SwipeView>
    </DataTemplate>
</CollectionView.ItemTemplate>

スワイプ項目がクリックされると、 MenuItem_Clicked メソッドが呼び出され、ムービーが削除されます。 スワイプ項目のバインド コンテキストは、現在のムービー、 MovieViewModel クラスです。 ただし、ムービーを削除するためのコードは、アプリのメイン ビューモデル MovieListViewModel にあります。 イベント ハンドラーは、スワイプ項目のバインド コンテキストを取得し、ビューモデルの DeleteMovie メソッドに送信するため、この事実を考慮します。

private void MenuItem_Clicked(object sender, EventArgs e)
{
    SwipeItem swipeItem = (SwipeItem)sender;
    ViewModels.MovieViewModel movie = (ViewModels.MovieViewModel)swipeItem.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. Views\MoviesListPage.xaml ファイルを開きます。

  5. SwipeItemを更新して、Command パラメーターをDeleteMovieCommandにバインドします。 現在のバインディング コンテキストを CommandParameter として渡します。

    <SwipeItem Text="Delete"
               BackgroundColor="Red"
               Command="{Binding DeleteMovieCommand, Source={x:Static local:App.MainViewModel}}"
               CommandParameter="{Binding}" />
    

    Clicked イベント ハンドラーが SwipeItem から削除されていることに注意してください。

    バインディング コンテキストの Source は、ページ自体と同様に、アプリのメイン ビューモデルに設定されます。 SwipeItem のバインディング コンテキストはムービーのままであり、CommandParameter に渡されます。

  6. ビューの分離コード ファイル Views\MoviesListPage.xaml.cs を開き、 MenuItem_Clicked コードを削除します。

  7. アプリを実行し、いずれかの映画を左にスワイプします。 スワイプ アクションから [削除] を選択します。 ムービーがリストから削除されます。