ObservableValidator
ObservableValidator
, arabirimini uygulayan ve diğer uygulama modüllerine INotifyDataErrorInfo
sunulan özellikleri doğrulama desteği sağlayan bir temel sınıftır. Ayrıca öğesinden ObservableObject
devralır, INotifyPropertyChanged
bu nedenle ve INotifyPropertyChanging
uygular. Hem özellik değişikliği bildirimlerini hem de özellik doğrulamasını desteklemesi gereken her tür nesne için başlangıç noktası olarak kullanılabilir.
Platform API'leri: ObservableValidator, ObservableObject
Nasıl çalışır?
ObservableValidator
aşağıdaki ana özelliklere sahiptir:
- olayı ve diğer gerekli API'leri kullanıma sunan
ErrorsChanged
içinINotifyDataErrorInfo
temel bir uygulama sağlar. - Özellikleri otomatik olarak doğrulama ve değerlerini güncelleştirmeden önce gerekli olayları oluşturma olanağı sunan bir dizi ek
SetProperty
aşırı yükleme (temelObservableObject
sınıf tarafından sağlananların üzerinde) sağlar. - Buna benzer
SetProperty
ancak yalnızca doğrulama başarılı olursa hedef özelliği güncelleştirme ve daha fazla inceleme için oluşturulan hataları (varsa) döndürme özelliğine sahip olan bir diziTrySetProperty
aşırı yükleme sunar. - Değerinin
ValidateProperty
güncelleştirilmemesi ancak bunun yerine güncelleştirilmiş olan başka bir özelliğin değerine bağımlı olması durumunda belirli bir özelliğin doğrulamasını el ile tetiklemenin yararlı olabileceği yöntemini kullanıma sunar. - En az bir
[ValidationAttribute]
tane uygulanmış olması koşuluyla geçerli örnekteki tüm genel örnek özelliklerinin doğrulamasını otomatik olarak yürüten yöntemini kullanıma sunarValidateAllProperties
. - Kullanıcının yeniden doldurmak isteyebileceği bir forma bağlı modeli sıfırlarken yararlı olabilecek bir
ClearAllErrors
yöntemi kullanıma sunar. - Özellikleri doğrulamak için kullanılacak örneği başlatmak
ValidationContext
için farklı parametrelerin geçirilmesine olanak sağlayan bir dizi oluşturucu sunar. Bu, özellikle ek hizmetlerin veya seçeneklerin düzgün çalışmasını gerektirebilecek özel doğrulama özniteliklerini kullanırken yararlı olabilir.
Basit özellik
Hem değişiklik bildirimlerini hem de doğrulamayı destekleyen bir özelliğin nasıl uygulandığını gösteren bir örnek aşağıda verilmiştir:
public class RegistrationForm : ObservableValidator
{
private string name;
[Required]
[MinLength(2)]
[MaxLength(100)]
public string Name
{
get => name;
set => SetProperty(ref name, value, true);
}
}
Burada tarafından ObservableValidator
kullanıma sunulan yöntemini çağırıyoruz SetProperty<T>(ref T, T, bool, string)
ve için true
ayarlanan ek bool
parametre değeri güncelleştirildiğinde özelliğini de doğrulamak istediğimizi gösteriyor. ObservableValidator
özelliğine uygulanan özniteliklerle belirtilen tüm denetimleri kullanarak her yeni değerde doğrulamayı otomatik olarak çalıştırır. Daha sonra diğer bileşenler (ui denetimleri gibi) görünüm modeliyle etkileşime geçebilir ve değiştirilmiş olan her özelliğin hata listesini almak için yöntemini kullanarak GetErrors(string)
görünüm modelinde ErrorsChanged
mevcut olan hataları yansıtacak şekilde durumlarını değiştirebilir.
Özel doğrulama yöntemleri
Bazen bir özelliğin doğrulanıyor olması için görünüm modelinin ek hizmetlere, verilere veya diğer API'lere erişimi olması gerekir. Senaryoya ve gerekli esneklik düzeyine bağlı olarak bir özelliğe özel doğrulama eklemenin farklı yolları vardır. Aşağıda, bir özelliğin ek doğrulamasını [CustomValidationAttribute]
gerçekleştirmek için belirli bir yöntemin çağrılması gerektiğini belirtmek için türün nasıl kullanılabileceğini gösteren bir örnek verilmiştir:
public class RegistrationForm : ObservableValidator
{
private readonly IFancyService service;
public RegistrationForm(IFancyService service)
{
this.service = service;
}
private string name;
[Required]
[MinLength(2)]
[MaxLength(100)]
[CustomValidation(typeof(RegistrationForm), nameof(ValidateName))]
public string Name
{
get => this.name;
set => SetProperty(ref this.name, value, true);
}
public static ValidationResult ValidateName(string name, ValidationContext context)
{
RegistrationForm instance = (RegistrationForm)context.ObjectInstance;
bool isValid = instance.service.Validate(name);
if (isValid)
{
return ValidationResult.Success;
}
return new("The name was not validated by the fancy service");
}
}
Bu durumda, viewmodelimize eklenen bir hizmet aracılığıyla özelliğinde Name
doğrulama gerçekleştirecek statik ValidateName
bir yöntemimiz vardır. Bu yöntem, görünüm modeli örneği, doğrulanan özelliğin adı ve isteğe bağlı olarak bir hizmet sağlayıcısı ve ValidationContext
kullanabileceğimiz veya ayarlayabildiğimiz bazı özel bayraklar gibi öğeleri içeren özellik değerini ve kullanımdaki örneği alırname
. Bu durumda, doğrulama bağlamından RegistrationForm
örneği alıyoruz ve oradan özelliği doğrulamak için eklenen hizmeti kullanıyoruz. Bu doğrulamanın diğer özniteliklerde belirtilenlerin yanında yürütüleceğini unutmayın, bu nedenle özel doğrulama yöntemlerini ve mevcut doğrulama özniteliklerini istediğimiz gibi birleştirebiliriz.
Özel doğrulama öznitelikleri
Özel doğrulama yapmanın bir diğer yolu da özel [ValidationAttribute]
bir uygulama yapmak ve ardından geçersiz kılınan IsValid
yönteme doğrulama mantığını eklemektir. Bu, aynı özniteliği birden çok yerde yeniden kullanmanızı çok kolay hale getirdiğinden, yukarıda açıklanan yaklaşıma kıyasla daha fazla esneklik sağlar.
Bir özelliği, aynı görünüm modelindeki başka bir özelliğe göre göreli değerine göre doğrulamak istediğimizi varsayalım. İlk adım, aşağıdaki gibi özel [GreaterThanAttribute]
bir tanımlamak olacaktır:
public sealed class GreaterThanAttribute : ValidationAttribute
{
public GreaterThanAttribute(string propertyName)
{
PropertyName = propertyName;
}
public string PropertyName { get; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
object
instance = validationContext.ObjectInstance,
otherValue = instance.GetType().GetProperty(PropertyName).GetValue(instance);
if (((IComparable)value).CompareTo(otherValue) > 0)
{
return ValidationResult.Success;
}
return new("The current value is smaller than the other one");
}
}
Daha sonra bu özniteliği viewmodelimize ekleyebiliriz:
public class ComparableModel : ObservableValidator
{
private int a;
[Range(10, 100)]
[GreaterThan(nameof(B))]
public int A
{
get => this.a;
set => SetProperty(ref this.a, value, true);
}
private int b;
[Range(20, 80)]
public int B
{
get => this.b;
set
{
SetProperty(ref this.b, value, true);
ValidateProperty(A, nameof(A));
}
}
}
Bu durumda, belirli bir aralıkta ve aralarında belirli bir ilişkiye sahip olması gereken iki sayısal özelliğimiz vardır (A
değerinden B
büyük olması gerekir). Yeniyi [GreaterThanAttribute]
ilk özelliğin üzerine ekledik ve ayrıca için ayarlayıcıya B
ValidateProperty
bir çağrı ekledik, böylece A
her değişiklik olduğunda B
yeniden doğrulanır (geçerlilik durumu buna bağlı olduğundan). Bu özel doğrulamayı etkinleştirmek için görünüm modelimizdeki bu iki kod satırına ihtiyacımız var ve ayrıca uygulamamızdaki diğer görünüm modellerinde de yararlı olabilecek yeniden kullanılabilir bir özel doğrulama özniteliğine sahip olma avantajını elde ediyoruz. Doğrulama mantığı artık görünüm modeli tanımının kendisinden tamamen ayrılmış olduğundan bu yaklaşım kod modülerleştirmeye de yardımcı olur.
Örnekler
- MVVM Araç Seti'ni uygulamada görmek için örnek uygulamaya (birden çok UI çerçevesi için) göz atın.
- Birim testlerinde daha fazla örnek de bulabilirsiniz.
MVVM Toolkit