Saya ingin menangani Closing
acara (ketika pengguna mengklik tombol 'X' kanan atas) dari jendela saya untuk akhirnya menampilkan pesan konfirmasi atau / dan membatalkan penutupan.
Saya tahu bagaimana melakukan ini di kode-belakang: berlangganan Closing
acara jendela kemudian gunakan CancelEventArgs.Cancel
properti.
Tapi saya menggunakan MVVM jadi saya tidak yakin itu pendekatan yang baik.
Saya pikir pendekatan yang baik adalah dengan mengikat Closing
acara ke Command
dalam ViewModel saya.
Saya mencobanya:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding CloseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Dengan yang terkait RelayCommand
dalam ViewModel saya tetapi tidak berfungsi (kode perintah tidak dijalankan).
Jawaban:
Saya hanya akan mengasosiasikan pawang di konstruktor View:
Kemudian tambahkan handler ke
ViewModel
:Dalam hal ini, Anda tidak mendapatkan apa pun kecuali kompleksitas dengan menggunakan pola yang lebih rumit dengan lebih banyak tipuan (5 garis tambahan
Command
pola XAML plus ).Mantra "nol kode di belakang" bukanlah tujuan itu sendiri, intinya adalah untuk memisahkan ViewModel dari View . Bahkan ketika peristiwa terikat dalam kode di belakang tampilan,
ViewModel
tidak tergantung pada tampilan dan logika penutupan dapat diuji unit .sumber
Kode ini berfungsi dengan baik:
ViewModel.cs:
dan di XAML:
berasumsi bahwa:
DataContext
satu wadah utama.xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL5"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
sumber
i
di dalam<i:Interaction.Triggers>
dan bagaimana cara mendapatkannya.xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Opsi ini bahkan lebih mudah, dan mungkin cocok untuk Anda. Di konstruktor View Model Anda, Anda dapat berlangganan acara penutupan Jendela Utama seperti ini:
Semua yang terbaik.
sumber
Berikut ini adalah jawaban sesuai dengan pola-MVVM jika Anda tidak ingin tahu tentang Window (atau acara apa pun) di ViewModel.
Dalam ViewModel tambahkan antarmuka dan implementasi
Di Jendela saya menambahkan acara Penutupan. Kode di belakang ini tidak merusak pola MVVM. View dapat mengetahui tentang model view!
sumber
IClosing
antarmuka, bukan hanya mengimplementasikanOnClosing
metode. Kalau tidak, paraDataContext as IClosing
pemain akan gagal dan kembalinull
Ya ampun, sepertinya banyak kode yang terjadi di sini untuk ini. Spa di atas memiliki pendekatan yang tepat untuk upaya minimal. Berikut ini adalah adaptasi saya (menggunakan MVVMLight tapi harus dikenali) ... Oh dan PassEventArgsToCommand = "True" yang pasti diperlukan seperti ditunjukkan di atas.
(kredit untuk Laurent Bugnion http://blog.galasoft.ch/archive/2009/10/18/clean-shutdown-in-silverlight-and-wpf-applications.aspx )
Dalam model tampilan:
dalam ShutdownService
RequestShutdown terlihat seperti berikut ini tetapi pada dasarnyaRequestShutdown atau apa pun namanya dinamai memutuskan apakah akan mematikan aplikasi atau tidak (yang dengan senang hati akan menutup jendela):
sumber
Penanya harus menggunakan jawaban STAS, tetapi bagi pembaca yang menggunakan prisma dan tanpa galasoft / mvvmlight, mereka mungkin ingin mencoba apa yang saya gunakan:
Dalam definisi di bagian atas untuk jendela atau kontrol pengguna, dll, tentukan namespace:
Dan tepat di bawah definisi itu:
Properti di viewmodel Anda:
Lampirkan delegatkomandalam konstruktor viewmodel Anda:
Akhirnya, kode yang ingin Anda jangkau pada saat menutup kontrol / jendela / apa pun:
sumber
Saya akan tergoda untuk menggunakan event handler dalam file App.xaml.cs Anda yang memungkinkan Anda memutuskan apakah akan menutup aplikasi atau tidak.
Misalnya Anda kemudian dapat memiliki sesuatu seperti kode berikut di file App.xaml.cs Anda:
Kemudian dalam kode MainWindowViewModel Anda, Anda dapat memiliki yang berikut ini:
sumber
Pada dasarnya, window event mungkin tidak ditugaskan ke MVVM. Secara umum, tombol Tutup menunjukkan kotak Dialog untuk meminta pengguna "save: yes / no / cancel", dan ini mungkin tidak dapat dicapai oleh MVVM.
Anda dapat menyimpan pengendali acara OnClosing, tempat Anda memanggil Model.Close.CanExecute () dan mengatur hasil boolean di properti acara. Jadi setelah panggilan CanExecute () jika benar, ATAU dalam acara OnClosed, panggil Model.Close.Execute ()
sumber
Saya belum melakukan banyak pengujian dengan ini tetapi tampaknya berhasil. Inilah yang saya pikirkan:
sumber
Kami menggunakan AttachedCommandBehavior untuk ini. Anda dapat melampirkan acara apa pun pada perintah pada model tampilan Anda menghindari kode apa pun di belakang.
Kami menggunakannya di seluruh solusi kami dan memiliki hampir nol kode di belakang
http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/
sumber
Menggunakan MVVM Light Toolkit:
Dengan asumsi bahwa ada perintah Exit dalam model tampilan:
Ini diterima dalam tampilan:
Di sisi lain, saya menangani
Closing
acara diMainWindow
, menggunakan instance dari ViewModel:CancelBeforeClose
memeriksa model tampilan saat ini dan mengembalikan true jika penutupan harus dihentikan.Semoga ini bisa membantu seseorang.
sumber
sumber