Kontrol item XAML; ikat ke koleksi C++/WinRT

Koleksi yang dapat secara efektif terikat ke kontrol item XAML dikenal sebagai koleksi yang dapat diamati. Ide ini didasarkan pada pola desain perangkat lunak yang dikenal sebagai pola pengamat. Topik ini menunjukkan cara menerapkan koleksi yang dapat diamati di C++/WinRT, dan cara mengikat kontrol item XAML ke koleksi tersebut (untuk info latar belakang, lihat Pengikatan data).

Jika Anda ingin mengikuti topik ini, kami sarankan Anda terlebih dahulu membuat proyek yang dijelaskan dalam kontrol XAML; ikat ke properti C++/WinRT. Topik ini menambahkan lebih banyak kode ke proyek tersebut, dan menambahkan ke konsep yang dijelaskan dalam topik tersebut.

Penting

Untuk konsep dan istilah penting yang mendukung pemahaman Anda tentang cara menggunakan dan menulis kelas runtime dengan C++/WinRT, lihat Menggunakan API dengan C++/WinRT dan API Penulis dengan C++/WinRT.

Apa arti yang dapat diamati untuk koleksi?

Jika kelas runtime yang mewakili koleksi memilih untuk menaikkan peristiwa IObservableVector<T>::VectorChanged setiap kali elemen ditambahkan ke dalamnya atau dihapus darinya, maka kelas runtime adalah koleksi yang dapat diamati. Kontrol item XAML dapat mengikat, dan menangani, peristiwa ini dengan mengambil koleksi yang diperbarui lalu memperbarui dirinya sendiri untuk menampilkan elemen saat ini.

Catatan

Untuk informasi tentang menginstal dan menggunakan C++/WinRT Visual Studio Extension (VSIX) dan paket NuGet (yang bersama-sama menyediakan templat proyek dan dukungan build), lihat Dukungan Visual Studio untuk C++/WinRT.

Menambahkan koleksi BookSkus ke BookstoreViewModel

Dalam kontrol XAML; mengikat properti C++/WinRT, kami menambahkan properti jenis BookSku ke model tampilan utama kami. Dalam langkah ini, kita akan menggunakan templat fungsi winrt::single_threaded_observable_vector factory untuk membantu kami menerapkan koleksi BookSku yang dapat diamati pada model tampilan yang sama.

Deklarasikan properti baru di BookstoreViewModel.idl.

// BookstoreViewModel.idl
...
runtimeclass BookstoreViewModel
{
    BookSku BookSku{ get; };
    Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
...

Catatan

Dalam daftar MIDL 3.0 di atas, perhatikan bahwa jenis properti BookSkus adalah IObservableVector dari BookSku. Di bagian berikutnya dari topik ini, kita akan mengikat sumber item ListBox ke BookSkus. Kotak daftar adalah kontrol item, dan untuk mengatur properti ItemsControl.ItemsSource dengan benar, Anda perlu mengaturnya ke nilai tipe IObservableVector, atau IVector, atau dari jenis interoperabilitas seperti IBindableObservableVector.

Peringatan

Kode yang ditampilkan dalam topik ini berlaku untuk C++/WinRT versi 2.0.190530.8 atau yang lebih baru. Jika Anda menggunakan versi yang lebih lama, maka Anda harus membuat beberapa tweak kecil pada kode yang ditampilkan. Dalam daftar MIDL 3.0 di atas, ubah properti BookSkus menjadi IObservableVector dari IInspectable. Lalu gunakan IInspectable (bukan BookSku) dalam implementasi Anda juga.

Simpan dan bangun. Salin stub aksesor dari BookstoreViewModel.h dan BookstoreViewModel.cpp di \Bookstore\Bookstore\Generated Files\sources folder (untuk detail selengkapnya, lihat topik sebelumnya, kontrol XAML; ikat ke properti C++/WinRT). Terapkan stub aksesor seperti ini.

// BookstoreViewModel.h
...
struct BookstoreViewModel : BookstoreViewModelT<BookstoreViewModel>
{
    BookstoreViewModel();

    Bookstore::BookSku BookSku();

    Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> BookSkus();

private:
    Bookstore::BookSku m_bookSku{ nullptr };
    Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> m_bookSkus;
};
...
// BookstoreViewModel.cpp
...
BookstoreViewModel::BookstoreViewModel()
{
    m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Atticus");
    m_bookSkus = winrt::single_threaded_observable_vector<Bookstore::BookSku>();
    m_bookSkus.Append(m_bookSku);
}

Bookstore::BookSku BookstoreViewModel::BookSku()
{
    return m_bookSku;
}

Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> BookstoreViewModel::BookSkus()
{
    return m_bookSkus;
}
...

Mengikat ListBox ke properti BookSkus

Buka MainPage.xaml, yang berisi markup XAML untuk halaman UI utama kami. Tambahkan markup berikut di dalam StackPanel yang sama dengan Tombol.

<ListBox ItemsSource="{x:Bind MainViewModel.BookSkus}">
    <ItemsControl.ItemTemplate>
        <DataTemplate x:DataType="local:BookSku">
            <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ListBox>

Di MainPage.cpp, tambahkan baris kode ke penanganan aktivitas Klik untuk menambahkan buku ke koleksi.

// MainPage.cpp
...
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    MainViewModel().BookSku().Title(L"To Kill a Mockingbird");
    MainViewModel().BookSkus().Append(winrt::make<Bookstore::implementation::BookSku>(L"Moby Dick"));
}
...

Sekarang bangun dan jalankan proyek. Klik tombol untuk menjalankan penanganan aktivitas Klik . Kami melihat bahwa implementasi Append memunculkan peristiwa untuk memberi tahu UI bahwa koleksi telah berubah; dan ListBox mengkueri ulang koleksi untuk memperbarui nilai Itemnya sendiri. Sama seperti sebelumnya, judul salah satu buku berubah; dan perubahan judul tersebut tercermin baik pada tombol maupun di kotak daftar.

API penting