演習 - ビューモデルを使って選択を管理する

完了

この演習では、人事のアプリの例から少し離れます。 代わりに、ムービーを一覧表示するアプリケーションを使用します。 アプリには、2 つのページと、いくつかの基本的なバインドを備えたビューモデルが既にあります。 その 2 つのページは、リスト ページと詳細ページです。 ここでは、ListView と詳細ページで同じビューモデルのプロパティを使うように、選択ロジックを変更します。

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

Note

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

この演習モジュールを開始するにあたり、Movie List Sample プロジェクトをダウンロードします。 このプロジェクトでは、ムービーの一覧が表示されます。 ムービーをクリックすると、ムービーに関する詳細情報が表示された詳細ページに移動します。

  1. Movie List Sample プロジェクトをダウンロードして、一時フォルダーに展開します。
  2. part4-exercise1 フォルダーに移動し、MovieCatalog.sln ソリューションを開きます。
  3. プロジェクトをビルドして実行し、プロジェクトが動作することを確認します。 表示された画面に、ムービーの一覧が表示されます。 一覧表示されているいずれかのムービーを選択すると、アプリが詳細ページに移動します。

コードを確認する

数分かけてビューモデルとビューがどのように構造化されているかを調べます。 XAML とデータ バインディングに慣れている場合は、目新しいものはないはずですが、構造には MVVM パターンが使われています。

MovieListViewModel は、アプリの全体的なビューモデルと、MoviesListPage のビューモデルという 2 つの役割を受け持っています。 このビューモデルには、モデルから読み込まれたムービーの一覧が含まれています。これは、プロジェクトに含まれる json ファイルです。 もう 1 つのビューモデルは MovieViewModel であり、1 つのムービーを表します。 これも、リスト ページの行にデータを提供することと、MovieDetailPageBindingContext という 2 つの役割を受け持っています。

選択のサポートを追加する

MoviesListPage は、アプリの実行時に最初に表示されるページです。 ページ上の ListView は、ビューモデル MovieListViewModel 全体で提供される MovieViewModel インスタンスのコレクションにバインドされます。 ビュー内のいずれかのムービーを選択すると、ItemTapped イベントは MovieDetailPage に移動し、ムービーである項目の BindingContext をビューのコンストラクターに渡します。 MovieDetailPage は、渡されたビューモデルをページの BindingContext として設定します。

代わりに、MovieDetailPage がアプリ全体のビューモデルから選択したムービーを読み取るようにアプリを更新しましょう。

  1. ソリューション エクスプローラー ウィンドウで、ViewModels\MovieListViewModel.cs ファイルを開きます。

  2. 以下のコードを MovieListViewModel クラスに追加します。

    private MovieViewModel _selectedMovie;
    
    public MovieViewModel SelectedMovie
    {
        get => _selectedMovie;
        set => SetProperty(ref _selectedMovie, value);
    }
    
  3. 次に、Views\MoviesListPage.xaml ファイルを開きます。

  4. ListView 要素を探して、SelectedItem 属性を追加します。

    <ListView ItemsSource="{Binding Movies}" SelectedItem="{Binding SelectedMovie, Mode=OneWayToSource}" Margin ... >
    

    この属性は、リストの選択項目をビューモデルの新しいプロパティにバインドします。

  5. ビュー Views\MoviesListPage.xaml.cs の分離コード ファイルを開きます。

  6. ListView_ItemTapped イベント ハンドラー コードを次のコードに置き換えます。

    private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        await Navigation.PushAsync(new Views.MovieDetailPage());
    }
    

    MovieDetailPage はコンストラクターでムービーを受け入れなくなりました。代わりに、新しいコンストラクターがアプリのメイン ビューモデルを読み取ります。

  7. Views\MovieDetailPage.xaml.cs ファイルを開き、コンストラクターを次のコードに変更します。

    public MovieDetailPage()
    {
    	BindingContext = App.MainViewModel.SelectedMovie;
    	InitializeComponent();
    }
    

    このコードによって、選択したムービーにビューのバインディング コンテキストが設定されます。

  8. アプリを実行し、コードが意図したとおりに動作することを確認します。