Microsoft-ui-xaml: Tambahkan Dukungan Validasi Input ke UWP dengan INotifyDataErrorInfo

Dibuat pada 14 Jan 2019  ·  50Komentar  ·  Sumber: microsoft/microsoft-ui-xaml

Proposal: Tambahkan Dukungan Validasi Input dengan INotifyDataErrorInfo

Ringkasan

Tambahkan Dukungan Validasi Input dengan INotifyDataErrorInfo yang didukung oleh x:Bind dan Binding. Kedua Ekstensi Markup harus mendapatkan properti ValidatesOnNotifyDataErrors baru yang - seperti di Binding WPF - benar secara default.

Alasan

Saat ini UWP tidak memiliki Validasi Input yang dibangun ke dalam platform. Tetapi setiap lini aplikasi bisnis memerlukan validasi input. Ini adalah salah satu fitur terpenting untuk aplikasi perusahaan yang tepat. Ada entri di suara pengguna yang mengatakan fitur ini akan datang dengan WinUI, tetapi saya belum melihat apa pun: https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/13052589-uwp-input -validasi

feature proposal needs-winui-3 team-Markup

Komentar yang paling membantu

INDEI mengharuskan Anda untuk mengimplementasikan semua entitas dan sub entitas Anda.

Bisakah Anda menguraikan lebih lanjut tentang ini?

Menggunakan aturan, tidak ada perubahan yang diperlukan, semuanya bekerja secara otomatis menggunakan atribut validasi saja.

Sebagian besar, semuanya bekerja secara otomatis saat menggunakan ValidationAttributes dan INotifyDataErrorInfo juga. Saya akan menunjukkan beberapa cuplikan kode di sini yang ada dalam spesifikasi, supaya kita (semoga) berada di halaman yang sama.

FWIW, kami berencana untuk menampilkan kelas ValidationBase ini di Toolkit, jadi Anda tidak perlu menulis sendiri kode boilerplate ini.

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Model Anda kemudian akan diturunkan dari kelas itu dan terlihat seperti ini:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Dengan asumsi kelas Person ini disetel ke properti ViewModel pada Page Anda, Anda kemudian mengikatnya, dan validasi terjadi secara otomatis:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Saya mengerti ini mungkin sedikit berbeda dari apa yang Anda lakukan hari ini, tetapi kami mencoba untuk tidak mendukung dua cara berbeda untuk melakukan hal yang sama jika tidak perlu. Beri tahu saya jika ini masuk akal, atau jika menurut Anda masih ada yang kurang dari kami!

Semua 50 komentar

@LucasHaines bagaimana ini berhubungan dengan fitur validasi input yang Anda cari?

@jevansaks Ini terkait langsung dengan pekerjaan Validasi Input yang saya uraikan.

Besar. Jika Anda memiliki hal-hal pratinjau untuk dibagikan, saya senang mencobanya dan memberikan umpan balik dan pemikiran.

image

Ini adalah jenis validasi yang disebutkan selama Build 2018

`
x:Name="UserName" Header="Nama Pengguna:"
Text="{x:Bind ViewModel.Person.UserName,
UpdateSourceTrigger=PropertyChanged,
Mode=Dua Arah}" />

x:Nama="Kata Sandi" Header="Kata Sandi:"
Password="{x:Ikat ViewModel.Person.Password,
UpdateSourceTrigger=LostFocus,
Mode=Dua Arah}"/>
`

@thomasclaudiushuber menurut Anda seberapa pentingkah membuat ini berfungsi sebagai bagian dari {Binding}? Saya hanya bertanya karena kendala teknis di sana non-sepele, serta tidak bisa bekerja secara downlevel. Ide awal kami adalah hanya mendukung x:Bind, yang hanya memerlukan perubahan kompiler markup, dan mampu bekerja di tingkat bawah.

Selain itu, kami hanya berencana mendukung paradigma INotifyDataErrorInfo dan DataAnnotations. Kami tidak bermaksud menambahkan sesuatu yang analog dengan Binding.ValidationRules, dan dengan demikian tidak merasa ada kebutuhan yang cukup untuk ValidatesOnNotifyDataErrors.

Kami ingin mendapatkan tanggapan Anda saat kami terus mengerjakan fitur ini sehingga dapat dilakukan dengan benar!

@stevenbrix

Jawaban singkat: Ya, apa yang Anda pikirkan dan rencanakan terdengar hebat. Just x:Bind baik-baik saja, dan hanya INotifyDataErrorInfo juga baik-baik saja.

Panjang:

Hanya x:Mengikat? 👍

Dalam semua kasus WPF-LOB saya bisa memikirkan selalu ada semacam ViewModel yang dikenal pada waktu kompilasi, tidak ada pengetikan bebek, jadi x:Bind baik-baik saja. Saya menulis {Binding} dalam masalah ini juga karena saya pikir Anda dapat mendukungnya untuk mendapatkan sintaks yang sama seperti di WPF. Tapi ini lebih "baik untuk dimiliki" daripada super penting. Dan karena {Binding} dan x:Bind adalah dua hal yang sangat berbeda di belakang layar dan hal-hal runtime dengan {Binding} tidak sepele seperti yang Anda sebutkan, lupakan {Binding}. Saya pikir memilikinya hanya untuk x: Bind benar-benar baik-baik saja, itu akan berfungsi untuk kasus penggunaan yang dapat saya pikirkan. Dan dari semua pembicaraan konferensi yang saya lakukan di UWP dan x:Bind, saya dapat memberi tahu Anda bahwa x:Bind adalah salah satu fitur UWP paling favorit dari semua pengembang XAML dan saya memberi tahu mereka semua "Lebih suka x:Bind daripada Binding di mana pun Anda bisa". :) Mendapatkan kesalahan intellisense, perf, langkah-ke-kode, dan waktu kompilasi membuat x:Bind default baru pada UWP, jadi memiliki dukungan validasi di sana baik-baik saja dan keputusan yang baik imo.

Hanya paradigma INotifyDataErrorInfo dan DataAnnotations? 👍

Hanya mendukung paradigma INotifyDataErrorInfo dan DataAnnotations terdengar bagus bagi saya. WPF tidak mengambil Anotasi Data secara otomatis, Anda perlu menghubungkannya secara manual dalam implementasi INotifyDataErrorInfo Anda dengan menggunakan kelas Validator. Maksud Anda ini ketika Anda mengatakan "paradigma DataAnnotations", bukan? Atau apakah Anda merencanakan dukungan DataAnnotation bawaan yang memungkinkan pengembang untuk hanya menempatkan Anotasi Data di properti dan ini berfungsi? Seperti di ASP.NET Core MVC? Meskipun itu akan bagus, saya pikir itu tidak perlu. Memiliki kelas ValidationContext, Validator dan ValidationResult dan kelas lain dari System.ComponentModel.DataAnnotations sudah cukup.

Tambahkan Binding.ValidationRules? ooo ;-)

Tidak, pasti tidak menambahkan itu. INotifyDataErrorInfo sudah cukup dan itu yang terbaik. Saya pikir saya tidak pernah menggunakan ValidationRules lagi setelah dukungan IDataErrorInfo ditambahkan ke WPF (Jika saya ingat dengan benar ini ada di .NET Framework 3.5). Dan ketika INotifyDataErrorInfo ditambahkan di .NET Framework 4.5, pelanggan saya dan saya telah menggunakan antarmuka itu di semua proyek untuk validasi input. Mendukung hanya antarmuka ini tidak masalah.

Tambahkan ValidatesOnNotifyDataErrors? Tidak tapi...

Ya, Anda tidak perlu menambahkan yang ini. Tapi itu tidak ada hubungannya dengan Binding.ValidationRules. Properti ini terkait langsung dengan antarmuka INotifyDataErrorInfo. Pada Ekstensi Markup Binding WPF, ValidatesOnNotifyDataErrors secara default benar, yang berarti {Binding} mengambil validasi INotifyDataErrorInfo yang diimplementasikan jika objek terikat mengimplementasikan antarmuka itu. Jika Anda menyetel properti ValidatesOnNotifyDataErrors pada ekstensi markup Binding ke false, Ekstensi Markup Binding tidak akan mengambil implementasi INotifyDataErrorInfo untuk validasi. Jadi, mungkin ini tidak terlalu sulit untuk diterapkan dengan x:Bind, tapi mungkin kita tidak membutuhkannya. Jadi, jangan lakukan itu. Tidak apa-apa untuk meninggalkan ini. Tapi izinkan saya menjelaskan skenario di mana saya membutuhkan ini di masa lalu:

Kontrol WPF menunjukkan secara default batas merah yang ditentukan melalui Validation.ErrorTemplate. Sekarang mari kita asumsikan Anda memiliki implementasi INotifyDataErrorInfo dengan kelas yang memiliki properti FirstName. Ini diperlukan, jadi Anda mengembalikan kesalahan jika properti FirstName adalah null atau kosong. Sekarang Anda mengikat TextBox ke properti FirstName itu. Saat pengguna menghapus nama depan itu, batas merah akan muncul. Bagus, persis seperti yang Anda inginkan. Tapi mungkin Anda memiliki di tempat lain di UI kontrol lain yang terikat ke properti FirstName juga. Misalnya TextBlock di Tab-Header. WPF akan menampilkan pada TextBlock itu batas merah juga ketika ada kesalahan validasi. Tapi ini mungkin bukan yang Anda inginkan. Anda ingin kesalahan hanya di TextBox di mana pengguna dapat mengubah nama depan, tetapi tidak di TextBlock di header Tab. Untuk menghilangkan batas merah pada TextBlock, Anda tidak perlu mengedit ErrorTemplate TextBlock, melainkan Anda cukup mengaktifkan validasi INotifyDataErrorInfo pada TextBlock-FirstName-Binding dengan menyetel properti ValidatesOnNotifyDataErrors ke false. Itulah satu-satunya kasus penggunaan yang pernah saya miliki untuk properti ini. :)

Saya harap ini membantu.

Ringkasan

Ya, saya sangat setuju, memiliki validasi input hanya di x:Bind dengan dukungan untuk INotifyDataErrorInfo adalah rencana yang bagus.

Tidak, ini rencana yang fantastis, saya sudah sangat bersemangat!

@thomasclaudiushuber terima kasih atas tindak lanjut yang mendetail! Skenario inti yang Anda gambarkan sejalan dengan apa yang kami yakini sebagai pendorong nilai sebenarnya, dan itu bagus untuk didengar. Desain keseluruhan fitur dan API ini telah berubah, sebagian besar karena pekerjaan sebelumnya yang dimiliki WPF. Ada beberapa hal utama yang perlu disebutkan di sini:

  1. Seperti dibahas di atas, ada aspek tertentu dari sistem validasi WPF yang menurut kami tidak memiliki nilai tambah, atau digantikan oleh pola yang lebih baik, jadi kami tidak berencana membawanya ke UWP.

  2. Fitur/fungsi tertentu dari sistem validasi WPF memanfaatkan fitur inti WPF yang tidak ada di UWP. Yang paling menonjol di sini adalah lapisan penghias, yang memungkinkan setiap UIElement di WPF untuk menampilkan visual validasi, bukan hanya Kontrol (melalui menambahkan beberapa bagian template).

  3. UWP Xaml saat ini tidak memiliki konsep acara terlampir, dan mencerminkan kelas Validasi akan menambahkan acara Validation.Error. Bukan itu pemecah kesepakatan, hanya sesuatu untuk dipanggil karena kami umumnya berhati-hati dalam menambahkan konsep baru, karena hanya menambah kerumitan. Selain itu, karena pekerjaan memerlukan perubahan pada Template Kontrol, hanya kumpulan kontrol yang kami sediakan untuk perubahan template tertentu yang akan berfungsi di luar kotak. Secara umum, memiliki API yang tampaknya berfungsi, tetapi tidak dalam beberapa skenario bukanlah praktik yang baik, jadi kami berpikir akan lebih baik untuk memisahkan diri dari model itu. Ini berarti memiliki sesuatu yang lain seperti antarmuka umum dan/atau atribut yang mengontrol implementasi.

Kami masih dalam proses memahami cara melakukan tinjauan API dan spesifikasi di dunia open source yang baru dan menarik. Kami ingin mendapatkan umpan balik dari komunitas, jadi semoga kami dapat segera mengeluarkan proposal API sehingga komunitas dapat melihat dan membantu kami mendapatkan sesuatu yang membuat semua orang bersemangat!

@stevenbrix Ketika Anda memulai spesifikasi open source untuk fitur validasi, akankah Anda memberikan ilustrasi tentang bagaimana validasi akan terlihat, serta skenario sampel sehingga percakapan bisa sedikit lebih luas bagi kita yang lebih ke sisi UI , daripada coding :)

@mdtauk Tentu saja. UI saat ini yang kami bagikan masih akurat. Jika Anda memiliki umpan balik, jangan ragu untuk memberikan di utas ini.

@LucasHaines UI terlihat bagus untuk saya. Tapi saya bertanya-tanya bagaimana Anda dapat menyesuaikan bagaimana kesalahan ditampilkan. Saya belum menemukan apa pun tentang ini dan saya tidak tahu apakah Anda sudah memiliki sesuatu untuk dibagikan di area itu. Apakah akan ada sesuatu yang mirip seperti properti Validation.ErrorTemplate terlampir dari WPF?

Apakah ada batas waktu kapan spesifikasi/proposal formal akan dirilis untuk ini?
Apa yang dapat saya lakukan untuk membantu ini masuk ke produk lebih cepat?

Saya setuju dengan @mrlacey di atas... Saya benar-benar bisa menggunakan ini sekarang, jadi saya senang membantu di mana saya bisa.

Kami sedang mengerjakan spesifikasi terbuka dan saya akan memberi tahu semua orang bahwa itu tersedia di repo spesifikasi.

Pertanyaan: mengapa tidak mendukung IDataErrorInfo juga? Ini didukung dalam standar .net, dan akan aneh untuk tidak mendukungnya? Ini seharusnya tidak mempengaruhi kinerja untuk orang yang tidak menggunakannya karena bahkan dapat diperiksa pada waktu kompilasi antarmuka mana yang digunakan untuk pengikatan?

Kami memulai tinjauan spesifikasi terbuka untuk Validasi Input di repo spesifikasi terbuka. https://github.com/Microsoft/microsoft-ui-xaml-specs/pull/26

Hai teman-teman, bagaimana kami melacak ini - apakah kami memiliki ETA?

@knightmeister Kami memiliki spesifikasi terbuka yang dibuat di sini . Silakan berpartisipasi dalam peninjauan dan bantu membentuk fitur. Kami berencana untuk mengirimkan ini sebagai bagian dari WinUI 3.0. Jika Anda ingin informasi lebih lanjut tentang peta jalan WinUI 3.0, periksa masalah #717.

Hai Semuanya - silakan lihat contoh terbaru di spesifikasi. @stevenbrix membuat beberapa pembaruan hebat pada sampel dan mengatasi umpan balik lainnya.

Satu pertanyaan: akankah informasi validasi mengalir ke hierarki kontrol? Misalnya, apakah kontrol wadah (mis. TabView atau Pivot) mungkin untuk mengetahui bahwa ada kontrol anak dalam keadaan tidak valid?

Pikirkan tampilan kompleks dengan beberapa kontrol wadah, di mana Anda ingin menyorot bagian tampilan mana yang memerlukan perhatian, misalnya dengan mengubah gaya header Pivot saat kontrol anak dalam keadaan tidak valid.

Ini adalah masalah kritis bagi saya.
Seluruh sistem validasi XAML saya didasarkan pada aturan validasi WPF, ia membaca bidang dan model entitas dari BindingExpression dan membuat aturan validasi sesuai dengan atribut validasi DA (lihat this ).

Misalnya, apakah kontrol wadah (mis. TabView atau Pivot) mungkin untuk mengetahui bahwa ada kontrol anak dalam keadaan tidak valid?

@tbolon ya, ini adalah sesuatu yang bisa dilakukan, meskipun tidak mungkin ada dukungan bawaan di wadah tersebut untuk itu. Kami telah berpikir untuk membuat kontrol Form yang akan memiliki fungsi ini di dalamnya, tetapi mungkin saat ini sedang tertunda. Seperti di WPF, ada peristiwa ValidationError (nama itu bisa salah) yang setiap kontrol menyala ketika menjadi tidak valid/valid. Acara ini bukanlah acara yang dirutekan, jadi Anda harus berlangganan setiap elemen yang ingin Anda dengarkan.

Seluruh sistem validasi XAML saya didasarkan pada aturan validasi WPF,

@weitzhandler saat ini kami tidak berencana menambahkan sesuatu seperti ValidationRule ke WinUI. Apakah ada sesuatu yang menggunakan ini memberi Anda lebih dari menggunakan ValidationAttributes dan membuat model Anda mengimplementasikan INotifyDataErrorInfo ? Saya ingin melihat seperti apa Model dan XAML Anda untuk mendapatkan pemahaman yang lebih baik tentang skenario penggunaan Anda.

INDEI mengharuskan Anda untuk mengimplementasikan semua entitas dan sub entitas Anda.
Menggunakan aturan, tidak ada perubahan yang diperlukan, semuanya bekerja secara otomatis menggunakan atribut validasi saja.

INDEI mengharuskan Anda untuk mengimplementasikan semua entitas dan sub entitas Anda.

Bisakah Anda menguraikan lebih lanjut tentang ini?

Menggunakan aturan, tidak ada perubahan yang diperlukan, semuanya bekerja secara otomatis menggunakan atribut validasi saja.

Sebagian besar, semuanya bekerja secara otomatis saat menggunakan ValidationAttributes dan INotifyDataErrorInfo juga. Saya akan menunjukkan beberapa cuplikan kode di sini yang ada dalam spesifikasi, supaya kita (semoga) berada di halaman yang sama.

FWIW, kami berencana untuk menampilkan kelas ValidationBase ini di Toolkit, jadi Anda tidak perlu menulis sendiri kode boilerplate ini.

public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
   public event PropertyChangedEventHandler PropertyChanged;
   public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

   protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
   {
       if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
       {
           currentValue = newValue;
           OnPropertyChanged(propertyName, newValue);
       }
   }

   readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
   public bool HasErrors
   {
       get
       {
           return _errors.Any();
       }
   }
   public IEnumerable GetErrors(string propertyName)
   {
       return _errors[propertyName];
   }

   private void OnPropertyChanged(string propertyName, object value)
   {
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       Validate(propertyName, value);
   }

   private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
   {
       if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors = new List<ValidationResult>();
           _errors.Add(propertyName, errors);
       }

       errors.AddRange(results);
       ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
   }

   private void ClearErrors(string propertyName)
   {
       if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
       {
           errors.Clear();
           ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
       }
   }

   public void Validate(string memberName, object value)
   {
       ClearErrors(memberName);
       List<ValidationResult> results = new List<ValidationResult>();
       bool result = Validator.TryValidateProperty(
            value,
            new ValidationContext(this, null, null)
            {
                MemberName = memberName
            },
            results
            );

        if (!result)
        {
            AddErrors(memberName, results);
        }
    }
}

Model Anda kemudian akan diturunkan dari kelas itu dan terlihat seperti ini:

public class Person : ValidationBase
{
    private string name;
    [MinLength(4)]
    [MaxLength(6)]
    public string Name
    {   
        get { return name; }
        set { SetValue(ref name, value); }
    }
}

Dengan asumsi kelas Person ini disetel ke properti ViewModel pada Page Anda, Anda kemudian mengikatnya, dan validasi terjadi secara otomatis:

<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />

Saya mengerti ini mungkin sedikit berbeda dari apa yang Anda lakukan hari ini, tetapi kami mencoba untuk tidak mendukung dua cara berbeda untuk melakukan hal yang sama jika tidak perlu. Beri tahu saya jika ini masuk akal, atau jika menurut Anda masih ada yang kurang dari kami!

Anda benar, tetapi itu mengharuskan entitas Anda bukan POCO.
Saya harus mencobanya. Mungkin tidak terlalu buruk menggunakan kelas EntityBase di aplikasi LoB. Saya hanya terbiasa menggunakan POCO.

UWP tidak memiliki *HAVE Validation* !!!!!!! Saya baru saja memulai sebuah proyek. Kembali ke WPF sampai beberapa tahun.

@rufw91 saya tahu, kan?!

Apa kendala waktu Anda? Implementasi pertama dari ini adalah di alfa WinUI3, dan kita akan memiliki pratinjau untuk desktop WinUI segera hadir di //Build jangka waktu. Kami berencana RTM'ing pada akhir tahun

UWP tidak memiliki *HAVE Validation* !!!!!!! Saya baru saja memulai sebuah proyek. Kembali ke WPF sampai beberapa tahun.

Saya telah memutuskan untuk tetap menggunakan WPF untuk tahun-tahun mendatang juga. Saya sudah melakukan semuanya (WPF, SL, WP, UWP, dll), pada akhirnya hanya 1 teknologi yang tampaknya solid, yaitu WPF. Mungkin dalam beberapa tahun akan menarik untuk memeriksa di mana WinUI berada, tetapi saya lelah beralih ke teknologi baru dan ditinggalkan sendirian dalam kegelapan. WPF matang dan berfungsi dengan baik. Mungkin dalam beberapa tahun Windows sebagai OS tidak relevan sama sekali, jadi mari kita tunggu sebelum melakukan investasi lagi di platform.

Mungkin dalam beberapa tahun Windows sebagai OS tidak relevan sama sekali, jadi mari kita tunggu sebelum melakukan investasi lagi di platform.

Menimbang bahwa kami baru saja melampaui 1 miliar penginstalan Windows 10, saya sulit percaya bahwa itu akan menjadi kenyataan. Tapi saya pasti merasakan frustrasi Anda dan tidak menyalahkan Anda karena tetap menggunakan WPF. FWIW, tim kami mengambil alih kepemilikan WPF sekarang, jadi beri tahu saya jika ada sesuatu yang Anda ingin kami lakukan di sana.

INDEI mengharuskan Anda untuk mengimplementasikan semua entitas dan sub entitas Anda.

Bisakah Anda menguraikan lebih lanjut tentang ini?

Dengan kode saya, semua entitas POCO dapat tetap bebas mengimplementasikan antarmuka tersebut, dan tetap tanpa kelas dasar. INPC diimplementasikan secara otomatis menggunakan Fody. Sebagian besar yang akan saya lakukan adalah mengimplementasikan IValidatableObject ketika validasi yang lebih halus diperlukan. Dan itu bekerja pada sub-tipe juga.

FWIW, kami berencana untuk menampilkan kelas ValidationBase ini di Toolkit, jadi Anda tidak perlu menulis sendiri kode boilerplate ini.

Itu tidak baik. Bagaimana jika entitas saya sudah memiliki kelas dasar? Itu juga mengapa saya bukan penggemar berat INotifyDataErrorInfo . Properti INPC sudah memusingkan diri mereka sendiri, terutama ketika berhadapan dengan aplikasi data besar dengan banyak entitas.

Cukup mengejutkan bahwa UWP belum memiliki validasi yang tepat. Itu adalah fitur dasar yang penting di hampir semua aplikasi dan harus diberikan prioritas pertama.

Cukup mengejutkan bahwa UWP belum memiliki validasi yang tepat. Itu adalah fitur dasar yang penting di hampir semua aplikasi dan harus diberikan prioritas pertama.

Yup, itu sebabnya kami sedang mengerjakannya :)

Itu tidak baik. Bagaimana jika entitas saya sudah memiliki kelas dasar?

Saya hanya mencoba memahami penggunaan Anda di sini. Apa kelas dasar, dan dapatkah itu berasal dari kelas ini?

Yup, itu sebabnya kami sedang mengerjakannya :)

Terima kasih, sangat dihargai. Ini, dan sisa pekerjaanmu.
Apa yang disiratkan oleh label need-winui-3 ?

Saya hanya mencoba memahami penggunaan Anda di sini. Apa kelas dasar, dan dapatkah itu berasal dari kelas ini?

Saya menggunakan Layanan Terhubung OData untuk membuat entitas dibuat di klien saya.
Objek yang dihasilkan adalah dari pola ini:

c# public abstract partial class ContactBase : Microsoft.OData.Client.BaseEntityType, INotifyPropertyChanged

Apa yang disiratkan oleh label need-winui-3?

@weitzhandler
Ini menyiratkan Validasi Input akan datang dengan WinUI 3. (3.0 seperti yang direncanakan saat ini). Itu mungkin tidak akan datang ke WinUI 2 karena itu akan membutuhkan perubahan pada kode OS XAML yang sekarang dalam mode pemeliharaan.

Saya menggunakan UWP di aplikasi Uno Platform. Semoga WinUI akan tercakup saat dirilis.
Terima kasih untuk pembaruannya!

Saya hanya mencoba memahami penggunaan Anda di sini. Apa kelas dasar, dan dapatkah itu berasal dari kelas ini?

Memiliki kelas dasar sering kali diamanatkan oleh pihak ketiga, misalnya kerangka kerja ketekunan yang Anda gunakan. UWP/WinUI juga menuntut kelas dasar hanya untuk validasi bukanlah pilihan. Itu perlu antarmuka agar berguna, tidak ada aplikasi kita yang bisa menggunakan kelas dasar. (Itu tidak berarti Anda tidak dapat memiliki kelas dasar untuk orang yang ingin menggunakannya, itu hanya perlu opsional dan bukan satu-satunya cara untuk melakukan validasi.)

Memiliki kelas dasar sering kali diamanatkan oleh pihak ketiga, misalnya kerangka kerja ketekunan yang Anda gunakan. UWP/WinUI juga menuntut kelas dasar hanya untuk validasi bukanlah pilihan. Itu perlu antarmuka agar berguna, tidak ada aplikasi kita yang bisa menggunakan kelas dasar.

Mari kita mundur sedikit. Saya pikir beberapa komentar terakhir yang saya buat telah menyebabkan sedikit kebingungan, yang merupakan kesalahan saya.

Semua yang dibutuhkan oleh model adalah untuk mengimplementasikan System.ComponentModel.INotifyDataErrorInfo (atau Windows.UI.Xaml.Data.INotifyDataErrorInfo untuk C++). Kompiler akan menghasilkan kode dengan benar untuk menghubungkannya dengan tampilan Anda saat menggunakan {x:Bind} .

Kelas ValidationBase yang saya rujuk di atas adalah kelas pembantu yang kami rencanakan untuk dikirimkan dalam perangkat komunitas yang mengimplementasikan ini, bersama dengan INotifyPropertyChanged . Tidak perlu menurunkannya jika kasus penggunaan Anda tidak mengizinkannya.

Terima kasih atas klarifikasi Anda @stevenbrix.

Bagaimana dengan atribut validasi dan IValidatableObject , apakah mereka akan dihormati oleh runtime UWP?

Bagaimana dengan atribut lain, seperti atribut MaxLength yang Anda sebutkan sebelumnya, apakah panjang maksimum TextBox akan diatur secara otomatis seperti di ASP.NET?
Sama dengan DataTypeAttribute , EditableAttribute .
Juga DisplayAttribute untuk menghasilkan header bidang.
Sejauh yang saya ingat mereka semua didukung di Silverlight.

(lihat ini ).

Bagaimana dengan atribut validasi dan IValidatableObject, apakah mereka akan dihormati oleh runtime UWP?

Jadi saat ini kami akan memiliki dukungan untuk atribut Required . Beberapa kontrol akan secara otomatis menempatkan tanda bintang kecil di sebelah teks header saat ini digunakan. Kami terbuka untuk mendukung lebih banyak lagi di masa mendatang jika Anda mau. Silakan buka masalah terpisah jika Anda ingin melihat lebih banyak, dan hanya untuk menetapkan harapan, dukungan atribut tambahan apa pun sangat tidak mungkin untuk membuat rilis awal WinUI3.

Adapun IValidatableObject , saya tidak yakin bagaimana itu akan berhasil. Sebagai generalisasi, mesin kami bekerja hanya dengan mendengarkan acara INotifyDataErrorInfo.ErrorsChanged . Validasi model yang sebenarnya terserah pengembang aplikasi, dan umumnya dilakukan saat mentransfer nilai dari target ke sumber.

Mungkin sebagai metode alternatif untuk ValidationBase yang Anda usulkan, harus ada satu set metode ekstensi, yang menjalankan proses validasi menggunakan Validator.TryValidateObject , dan menyuntikkan hasil validasi ke dalam entitas, memberitahukan perubahan ?
Dengan cara ini, itu dapat dicapai dengan mudah hanya dengan menerapkan INotifyDataErrorInfo . Kita juga dapat memiliki antarmuka yang mewarisi dari INotifyDataErrorInfo yang menambahkan properti yang menyimpan kumpulan kesalahan, sehingga runtime UWP atau toolkit dapat mengenali sebagai entitas yang dapat divalidasi secara otomatis, dan menyetel properti secara otomatis jika diterapkan.

Mungkin sebagai metode alternatif untuk ValidationBase yang Anda usulkan, harus ada satu set metode ekstensi, yang menjalankan proses validasi menggunakan Validator.TryValidateObject, dan menyuntikkan hasil validasi ke entitas, memberitahukan perubahannya?

Ini adalah ide bagus :)

Ingin tahu apakah paradigma generator sumber baru dapat membantu di sini juga?

Ya @michael-hawker, saya suka pemikiran Anda!

Saya memiliki pemikiran yang sama beberapa waktu yang lalu ketika saya pertama kali membaca tentang kemungkinan generator sumber baru.

Saya pikir dengan paradigma generator sumber baru kita dapat membangun/menghasilkan banyak hal di balik layar untuk INotifyDataErrorInfo dan INotifyPropertyChanged.

Saya memiliki kursus WPF di Pluralsight yang melakukan hal ini dengan T4, INotifyPropertyChanged dan INotifyDataErrorInfo, termasuk Anotasi Data untuk validasi: https://www.pluralsight.com/courses/wpf-mvvm-advanced-model-treatment
Kursus ini juga menggunakan Properti Terlampir khusus untuk menghubungkan berbagai hal.
Tujuan kursus ini adalah untuk menunjukkan bagaimana Anda dapat membangun aplikasi MVVM WPF yang muncul di setiap bidang input jika itu diubah dan berapa nilai aslinya.

Jadi, tentu saja, menghasilkan sesuatu dan mungkin berakhir dengan perpustakaan (mungkin sebagai bagian dari WCT) akan luar biasa. Dan saya ingin mengulang kursus itu untuk WinUI. :)

@rufw91 saya tahu, kan?!

Apa kendala waktu Anda? Implementasi pertama dari ini adalah di alfa WinUI3, dan kita akan memiliki pratinjau untuk desktop WinUI segera hadir di //Build jangka waktu. Kami berencana RTM'ing pada akhir tahun

@stevenbrix Saya harap begitu, saya harus beralih kembali ke WPF, saya sebenarnya baru saja selesai sekarang.

Saya membuka yang ini .

Untuk menindaklanjuti ini, setelah percakapan dengan @stevenbrix di Twitter, saya telah mengintegrasikan implementasi dasar INotifyDataErrorInfo yang dia berikan di sini ke dalam kelas ObservableValidator baru yang disertakan dalam MVVM Toolkit baru ( Microsoft.Toolkit.Mvvm library), yang juga mengimplementasikan INotifyPropertyChanged dan INotifyPropertyChanging

Anda dapat melihat kode terkait dan rekap semua yang terkait dengan perpustakaan itu dalam edisi ini .
Saya juga menyertakan tautan di sana ke masalah asli untuk MVVM Toolkit, serta lebih banyak dokumen untuk pengembang baru.

Bisakah Anda memberi kami pembaruan tentang ini? Penasaran apakah UWP 10.0 18362 mendukung INotifyDataErrorInfo . Menurut halaman dokumentasi berikut, https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=netcore-3.1 INotifyDataErrorInfo "berlaku" untuk UWP 10.0. Namun, dengan UWP 10.0 18362 diinstal dan ditargetkan, kotak teks tidak menampilkan validasi INotifyDataErrorInfo . Kotak teks dijelaskan dalam XAML sebagai berikut:

<TextBox Text="{x:Bind ViewModel.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Dan kami menggunakan ReactiveValidationObject sebagai implementasi INotifyDataErrorInfo di sini.

@worldbeater ini hanya tersedia di pratinjau terbaru WinUI3, apakah Anda menggunakannya?

Terima kasih @stevenbrix! Akan mencoba WinUI3. Senang mendengar INotifyDataErrorInfo dan UWP berteman, akhirnya

@worldbeater , ini masih dalam pratinjau, jadi kami ingin mendapatkan tanggapan Anda tentangnya! 💪.

@worldbeater omong-omong, dokumen mengatakan itu tersedia di UWP 10.0, tetapi itu tidak berarti itu didukung olehnya. Dokumentasi tidak cukup jelas.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat