Share via


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 ObservableObjectdevralı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çin INotifyDataErrorInfotemel 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 (temel ObservableObject 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 dizi TrySetProperty 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 ObservableValidatorkullanı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 Bbüyük olması gerekir). Yeniyi [GreaterThanAttribute] ilk özelliğin üzerine ekledik ve ayrıca için ayarlayıcıya BValidateProperty 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