Praktik Terbaik Aturan Pengikatan dan Validasi Data WPF

101

Saya memiliki aplikasi WPF yang sangat sederhana di mana saya menggunakan data binding untuk memungkinkan pengeditan beberapa objek CLR kustom. Sekarang saya ingin memasukkan beberapa validasi input ketika pengguna mengklik simpan. Namun, semua buku WPF yang telah saya baca tidak benar-benar memberikan ruang apa pun untuk masalah ini. Saya melihat bahwa Anda dapat membuat ValidationRules kustom, tetapi saya bertanya-tanya apakah ini akan berlebihan untuk kebutuhan saya.

Jadi pertanyaan saya adalah ini: apakah ada contoh aplikasi atau artikel yang baik di suatu tempat yang menunjukkan praktik terbaik untuk memvalidasi input pengguna di WPF?

Mark Heath
sumber

Jawaban:

83

Saya pikir cara baru yang lebih disukai mungkin menggunakan IDataErrorInfo

Baca lebih lanjut di sini

rudigrobler
sumber
3
Saya juga menemukan kerangka kerja Cinch ( cinch.codeplex.com ), yang menyertakan demo validasi praktik terbaik di WPF + MVVM, dan menggunakan IDataErrorInfo
Mark Heath
3
Dalam .NET 4.5 Anda dapat menggunakan INotifyErrorInfo yang memungkinkan Anda mengembalikan objek, bukan hanya string.
Peter
24

Dari dokumentasi Pola & Praktek MS :

Validasi Data dan Pelaporan Kesalahan

Model atau model tampilan Anda akan sering kali diminta untuk melakukan validasi data dan memberi sinyal error validasi data apa pun ke tampilan sehingga pengguna dapat bertindak untuk memperbaikinya.

Silverlight dan WPF menyediakan dukungan untuk mengelola kesalahan validasi data yang terjadi saat mengubah properti individual yang terikat ke kontrol dalam tampilan. Untuk properti tunggal yang terikat data ke sebuah kontrol, model atau model tampilan dapat memberi sinyal kesalahan validasi data dalam penyetel properti dengan menolak nilai buruk yang masuk dan melontarkan pengecualian. Jika properti ValidatesOnExceptions pada pengikatan data benar, mesin pengikat data di WPF dan Silverlight akan menangani pengecualian dan menampilkan isyarat visual kepada pengguna bahwa ada kesalahan validasi data.

Namun, membuang pengecualian dengan properti dengan cara ini harus dihindari jika memungkinkan. Pendekatan alternatifnya adalah dengan mengimplementasikan antarmuka IDataErrorInfo atau INotifyDataErrorInfo pada model tampilan atau kelas model Anda. Antarmuka ini memungkinkan model atau model tampilan Anda melakukan validasi data untuk satu atau beberapa nilai properti dan mengembalikan pesan kesalahan ke tampilan sehingga pengguna dapat diberi tahu tentang kesalahan tersebut.

Dokumentasi selanjutnya menjelaskan cara mengimplementasikan IDataErrorInfo dan INotifyDataErrorInfo.

Menepuk
sumber
3
Saya khawatir pada awalnya ketika saya melihat rekomendasi lemparan pengecualian. senang melihat yang diikuti dengan "membuang pengecualian dengan properti dengan cara ini harus dihindari jika memungkinkan"
kenwarner
22
Perlu juga dicatat bahwa beberapa muppet di microsoft memutuskan untuk tidak menyertakan INotifyDataErrorInfo di .net4 tetapi Hanya di silverlight. ini
menyebalkan
5
@ al3891- ini akan diurutkan dalam .NET 4.5- msdn.microsoft.com/en-us/library/…
RichardOD
@ aL3891 Apakah ada alternatif untuk INotifyDataErrorInfo yang hilang?
AgentKnopf
10

personaly, saya menggunakan pengecualian untuk menangani validasi. itu membutuhkan langkah-langkah berikut:

  1. di ekspresi data binding, Anda perlu menambahkan "ValidatesOnException = True"
  2. di objek data yang Anda ikat, Anda perlu menambahkan pengendali DependencyPropertyChanged di mana Anda memeriksa apakah nilai baru memenuhi kondisi Anda - jika tidak - Anda mengembalikan ke nilai lama objek (jika perlu) dan Anda melempar pengecualian.
  3. di template kontrol yang Anda gunakan untuk menampilkan nilai yang tidak valid di kontrol, Anda dapat mengakses Koleksi kesalahan dan menampilkan pesan pengecualian.

triknya di sini, adalah mengikat hanya ke objek yang berasal dari DependencyObject. implementasi sederhana INotifyPropertyChanged tidak akan berfungsi - ada bug dalam kerangka kerja, yang mencegah Anda mengakses kumpulan kesalahan.

Greg
sumber
3

Cek juga artikel ini . Seharusnya Microsoft merilis Enterprise Library (v4.0) mereka dari pola dan praktik mereka di mana mereka mencakup subjek validasi tetapi entah mengapa mereka tidak menyertakan validasi untuk WPF, jadi posting blog yang saya arahkan kepada Anda, menjelaskan apa yang penulisnya lakukan untuk mengadaptasinya. Semoga ini membantu!

murki
sumber
2

Anda mungkin tertarik dengan contoh aplikasi BookLibrary dari WPF Application Framework (WAF) . Ini menunjukkan bagaimana menggunakan validasi di WPF dan bagaimana mengontrol tombol Simpan ketika ada kesalahan validasi.

jbe
sumber
0

Jika kelas bisnis Anda secara langsung digunakan oleh UI Anda, lebih baik menggunakan IDataErrorInfo karena menempatkan logika lebih dekat dengan pemiliknya.

Jika kelas bisnis Anda adalah kelas rintisan yang dibuat dengan referensi ke layanan WCF / XmlWeb maka Anda tidak dapat / tidak boleh menggunakan IDataErrorInfo atau membuang Exception untuk digunakan dengan ExceptionValidationRule. Sebaliknya Anda dapat:

  • Gunakan ValidationRule kustom.
  • Tentukan kelas parsial dalam proyek UI WPF Anda dan terapkan IDataErrorInfo.
Alex Pollan
sumber
1
Saya tahu ini sudah tua, tapi saya berharap Alex akan bisa menanggapi. Ini adalah kesimpulan yang juga saya dapatkan, tetapi masalahnya adalah Anda harus menulis beberapa validasi untuk (misalnya) properti "Age" yang tidak boleh lebih besar dari 100 di ValidationRule, lalu ulangi logika yang sama di antarmuka IDataErrorInfo , yang menduplikasi logika tersebut. Apakah ada jalan lain untuk itu?
JFTxJ
Di mana Anda menduplikasi logika tersebut? dalam beberapa jenis validasi server? Saya kira dengan komentar Anda bahwa Anda memvalidasi dengan IDataErrorInfo di UI dan menduplikasi validasi di objek bisnis, bukan? Jika demikian, maka validasi di kedua sisi itu benar. Objek bisnis tidak dapat mempercayai UI dan harus melakukan validasinya sendiri (meskipun tampaknya duplikasi)
Alex Pollan
Tidak, duplikasi logika validasi ada di IDataErrorInfo dan di Aturan Validasi Kustom ... Karena Aturan Validasi Kustom adalah satu-satunya cara untuk memvalidasi data SEBELUM diperbarui ke objek terikat, validasi itu (Usia harus lebih rendah kemudian 100) harus ditentukan di IDataErrorInfo untuk menampilkan pesan "per-field", tetapi juga harus diterapkan dalam Aturan Validasi Kustom. Masuk akal?
JFTxJ