Dalam aplikasi WPF menggunakan MVVM, saya memiliki kontrol pengguna dengan item listview. Dalam waktu proses, ini akan menggunakan penyatuan data untuk mengisi tampilan daftar dengan kumpulan objek.
Apa cara yang benar untuk melampirkan peristiwa klik ganda ke item dalam tampilan daftar sehingga ketika item dalam tampilan daftar diklik dua kali, peristiwa yang sesuai dalam model tampilan diaktifkan dan memiliki referensi ke item yang diklik?
Bagaimana hal itu dapat dilakukan dengan cara MVVM yang bersih, yaitu tidak ada kode di belakang dalam Tampilan?
Saya bisa mendapatkan ini untuk bekerja dengan .NET 4.5. Tampak lurus ke depan dan tidak perlu pihak ketiga atau kode di belakang.
sumber
InputBindings
tersedia dari .NET 3.0 dan tidak tersedia di Silverlight.Saya suka menggunakan Perilaku dan Perintah Terlampir . Marlon Grech memiliki implementasi yang sangat baik dari Perilaku Perintah Terlampir. Dengan menggunakan ini, kita kemudian dapat menetapkan gaya ke properti ItemContainerStyle ListView yang akan menyetel perintah untuk setiap ListViewItem.
Di sini kami menetapkan perintah untuk diaktifkan pada acara MouseDoubleClick, dan CommandParameter, akan menjadi objek data yang kami klik. Di sini saya melakukan perjalanan ke atas pohon visual untuk mendapatkan perintah yang saya gunakan, tetapi Anda dapat dengan mudah membuat perintah luas aplikasi.
Untuk perintah, Anda dapat mengimplementasikan ICommand secara langsung, atau menggunakan beberapa pembantu seperti yang ada di MVVM Toolkit .
sumber
acb:
= AttachedCommandBehavior. Kode dapat ditemukan di tautan pertama dalam jawabanSaya telah menemukan cara yang sangat mudah dan bersih untuk melakukan ini dengan pemicu Blend SDK Event. Membersihkan MVVM, dapat digunakan kembali dan tidak ada kode di belakang.
Anda mungkin sudah memiliki sesuatu seperti ini:
Sekarang sertakan ControlTemplate untuk ListViewItem seperti ini jika Anda belum menggunakannya:
GridViewRowPresenter akan menjadi root visual dari semua elemen "di dalam" yang menyusun elemen baris daftar. Sekarang kita dapat memasukkan pemicu di sana untuk mencari peristiwa yang diarahkan MouseDoubleClick dan memanggil perintah melalui InvokeCommandAction seperti ini:
Jika Anda memiliki elemen visual "di atas" GridRowPresenter (mungkin dimulai dengan kisi) Anda juga dapat meletakkan Pemicu di sana.
Sayangnya event MouseDoubleClick tidak dibuat dari setiap elemen visual (mereka berasal dari Controls, tetapi tidak dari FrameworkElements misalnya). Solusinya adalah dengan mendapatkan kelas dari EventTrigger dan mencari MouseButtonEventArgs dengan ClickCount 2. Ini secara efektif menyaring semua non-MouseButtonEvents dan semua MoseButtonEvents dengan ClickCount! = 2.
Sekarang kita bisa menulis ini ('h' adalah Namespace dari kelas helper di atas):
sumber
Saya menyadari bahwa diskusi ini sudah berumur satu tahun, tetapi dengan .NET 4, apakah ada pemikiran tentang solusi ini? Saya sangat setuju bahwa tujuan MVVM BUKAN untuk menghilangkan kode di belakang file. Saya juga merasa sangat yakin bahwa hanya karena sesuatu itu rumit, tidak berarti itu lebih baik. Inilah yang saya masukkan di kode di belakang:
sumber
Anda dapat menggunakan fitur Tindakan Caliburn untuk memetakan peristiwa ke metode pada ViewModel Anda. Dengan asumsi Anda memiliki
ItemActivated
metode pada AndaViewModel
, maka XAML yang sesuai akan terlihat seperti:Untuk detail lebih lanjut, Anda dapat memeriksa dokumentasi dan sampel Caliburn.
sumber
Saya merasa lebih mudah untuk menautkan perintah saat tampilan dibuat:
Dalam kasus saya
BindAndShow
terlihat seperti ini (updatecontrols + avalondock):Meskipun pendekatan tersebut harus bekerja dengan metode apa pun yang Anda miliki untuk membuka tampilan baru.
sumber
Saya melihat solusi dari rushui dengan InuptBindings tetapi saya masih tidak dapat mencapai area ListViewItem di mana tidak ada teks - bahkan setelah mengatur latar belakang menjadi transparan, jadi saya menyelesaikannya dengan menggunakan templat yang berbeda.
Template ini untuk saat ListViewItem telah dipilih dan aktif:
Template ini untuk saat ListViewItem telah dipilih dan tidak aktif:
Ini adalah gaya Default yang digunakan untuk ListViewItem:
Yang tidak saya suka adalah pengulangan dari TextBlock dan pengikatan teksnya, saya tidak tahu Saya bisa berkeliling menyatakan itu hanya di satu lokasi.
Saya harap ini membantu seseorang!
sumber
listviewitem
, mereka mungkin tidak peduli apakah itu sudah dipilih atau belum. Juga penting untuk dicatat bahwa efek sorotan mungkin juga perlu disesuaikan agar sesuai denganlistview
gayanya. Dipilih.Saya berhasil membuat fungsionalitas ini dengan framework .Net 4.7 dengan menggunakan pustaka interaktivitas, pertama-tama pastikan untuk mendeklarasikan namespace di file XAML
Kemudian atur Event Trigger dengan masing-masing InvokeCommandAction di dalam ListView seperti di bawah ini.
Melihat:
Mengadaptasi kode di atas seharusnya cukup untuk membuat acara klik ganda berfungsi pada ViewModel Anda, namun saya menambahkan Anda kelas Model dan Model Tampilan dari contoh saya sehingga Anda dapat memiliki gagasan lengkap.
Model:
Lihat Model:
Jika Anda membutuhkan implementasi kelas DelegateCommand .
sumber
Inilah perilaku yang dilakukan pada keduanya
ListBox
danListView
.Berikut kelas ekstensi yang digunakan untuk menemukan induk.
Pemakaian:
sumber