練習 - 使用 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

開啟入門解決方案

  1. 複製或下載練習存放庫

    注意

    最好將練習內容複製或下載至較短的資料夾路徑,例如 _C:\dev_,以免組建產生的檔案超過最大路徑長度。

  2. 瀏覽至 part4-exercise1 資料夾,並在 Visual Studio 或 Visual Studio Code 的資料夾中開啟 MovieCatalog.sln 解決方案。

  3. 建置並執行該專案以確定它能運作。 您會在顯示的畫面上看到電影清單。 選取其中一部列出的影片,應用程式會帶您前往詳細資料頁面。

檢查程式碼

花幾分鐘的時間檢查 ViewModel 和檢視的結構。 如果您對於 XAML 和資料繫結很熟悉,則應該會覺得其結構看起來很眼熟,但是其是使用 MVVM 模式建構的結構。

有一個具有雙重任務的 MovieListViewModel,可作為應用程式的整體 ViewModel 和 MoviesListPage 的 ViewModel。 此 ViewModel 包含從模型載入的電影清單,這是在專案中包含的 json 檔案。 另一個 ViewModel 是 MovieViewModel,且代表一部電影。 其也執行雙重任務:為清單頁面中的資料列提供資料,以及作為 MovieDetailPageBindingContext

新增選取項目支援

MoviesListPage 是應用程式執行時第一次顯示的頁面。 頁面上的 ListView 會繫結至整體 ViewModel (MovieListViewModel) 所提供的 MovieViewModel 執行個體集合。 當您選取檢視中其中一部電影時,ItemTapped 事件會帶您前往 MovieDetailPage,將項目的 BindingContext (也就是電影) 傳遞至檢視的建構函式。 MovieDetailPage 會設定傳遞為頁面 BindingContext 的 ViewModel。

相反地,讓我們更新應用程式,讓 MovieDetailPage 從整體應用程式的 ViewModel 讀取選取的電影。

  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 ... >
    

    這個屬性會將清單的選取項目繫結至 ViewModel 中的新屬性。

  5. 開啟檢視的程式碼後置檔案 Views\MoviesListPage.xaml.cs

  6. 以下列程式碼取代 ListView_ItemTapped 事件處理常式程式碼:

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

    MovieDetailPage 不再接受建構函式中的電影,而新的建構函式會讀取應用程式的主要 ViewModel。

  7. 開啟 Views\MovieDetailPage.xaml.cs 檔案,並將建構函式變更為下列程式碼:

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

    此程式碼會將檢視的繫結內容設定為選取的電影。

  8. 執行應用程式,並確認程式碼如預期般運作。