Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az ObservableValidator interfészt megvalósító INotifyDataErrorInfo alaposztály, amely támogatja a más alkalmazásmodulok számára elérhető tulajdonságok érvényesítését. Azt is örökli, ObservableObjectígy implementálja INotifyPropertyChanged és INotifyPropertyChanging is. Kiindulópontként használható minden olyan objektumhoz, amelyeknek támogatniuk kell a tulajdonságmódosítási értesítéseket és a tulajdonságérvényesítést.
Platform API-k:ObservableValidator, ObservableObject
Hogyan működik?
ObservableValidator a következő fő funkciókkal rendelkezik:
- Alapszintű implementációt biztosít a(z)
INotifyDataErrorInfoszámára, elérhetővé téve a(z)ErrorsChangedeseményt és a többi szükséges API-t. - További
SetPropertytúlterhelések sorozatát biztosítja (az alaposztályObservableObjectáltal biztosítottakon felül), amelyek lehetővé teszi a tulajdonságok automatikus érvényesítését és a szükséges események növelését az értékek frissítése előtt. - Számos
TrySetPropertytúlterhelést biztosít, amelyek aSetPropertymetódushoz hasonlóak, de csak akkor frissítik a célként megadott tulajdonságot, ha az érvényesítés sikeres, valamint visszaadják a létrehozott hibákat (ha vannak) további vizsgálat céljából. - Elérhetővé teszi a
ValidatePropertymetódust, amely hasznos lehet egy adott tulajdonság érvényesítésének manuális aktiválásához abban az esetben, ha az értéke nem frissült, de az érvényesítése egy másik, ehelyett frissített tulajdonság értékétől függ. - Elérhetővé teszi a
ValidateAllPropertiesmetódust, amely automatikusan végrehajtja az aktuális példány összes nyilvános példánytulajdonságának ellenőrzését, feltéve, hogy legalább egy[ValidationAttribute]van alkalmazva rájuk. - Olyan metódust
ClearAllErrorstesz elérhetővé, amely hasznos lehet egy olyan űrlaphoz kötött modell alaphelyzetbe állításakor, amelyet a felhasználó esetleg újra ki szeretne tölteni. - Számos konstruktort kínál, amelyek lehetővé teszik különböző paraméterek átadását a
ValidationContexttulajdonságok érvényesítéséhez használt példány inicializálásához. Ez különösen akkor lehet hasznos, ha olyan egyéni érvényesítési attribútumokat használ, amelyek további szolgáltatásokat vagy beállításokat igényelhetnek a megfelelő működéshez.
Egyszerű tulajdonság
Íme egy példa egy olyan tulajdonság implementálására, amely támogatja a változásértesítéseket és az ellenőrzést is:
public class RegistrationForm : ObservableValidator
{
private string name;
[Required]
[MinLength(2)]
[MaxLength(100)]
public string Name
{
get => name;
set => SetProperty(ref name, value, true);
}
}
Itt a(z) ObservableValidator által közzétett SetProperty<T>(ref T, T, bool, string) metódust hívjuk meg, és a további, true értékre állított bool paraméter azt jelzi, hogy a tulajdonságot akkor is ellenőrizni szeretnénk, amikor az értéke frissül.
ObservableValidator automatikusan futtatja az ellenőrzést minden új értéken a tulajdonságra alkalmazott attribútumokkal megadott összes ellenőrzés használatával. A többi összetevő (például a felhasználói felület vezérlői) ezután kezelhetik a nézetmodellt, és módosíthatják az állapotukat, hogy azok tükrözzék a nézetmodellben jelenleg előforduló hibákat. Ehhez regisztrálni kell ErrorsChanged a metódust, és GetErrors(string) lekérheti az egyes módosított tulajdonságok hibáinak listáját.
Egyéni érvényesítési módszerek
Előfordulhat, hogy egy tulajdonság érvényesítéséhez egy nézetmodellnek további szolgáltatásokhoz, adatokhoz vagy egyéb API-khoz kell hozzáférése. A forgatókönyvtől és a szükséges rugalmassági szinttől függően különböző módokon adhat hozzá egyéni érvényesítést egy tulajdonsághoz. Íme egy példa arra, hogy a [CustomValidationAttribute] típus hogyan jelezheti, hogy egy adott metódust kell meghívni egy tulajdonság további érvényesítéséhez:
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");
}
}
Ebben az esetben van egy statikus ValidateName módszerünk, amely egy olyan szolgáltatáson keresztül végez ellenőrzést a Name tulajdonságon, amelyet a nézetmodellbe injektálunk. Ez a metódus megkapja a name tulajdonság értékét és a ValidationContext használatban lévő példányt, amely olyan elemeket tartalmaz, mint a nézetmodell-példány, az érvényesítendő tulajdonság neve, valamint opcionálisan egy szolgáltató és néhány egyéni jelző, amelyet használhatunk vagy beállíthatunk. Ebben az esetben lekérjük a példányt az RegistrationForm érvényesítési környezetből, és onnan az injektált szolgáltatást használjuk a tulajdonság ellenőrzéséhez. Vegye figyelembe, hogy ez az ellenőrzés a többi attribútumban megadottak mellett lesz végrehajtva, így tetszés szerint kombinálhatjuk az egyéni érvényesítési módszereket és a meglévő érvényesítési attribútumokat.
Egyéni érvényesítési attribútumok
Az egyéni érvényesítés másik módja egy egyéni [ValidationAttribute] implementálása, majd az érvényesítési logika beillesztése a felülírt IsValid metódusba. Ez nagyobb rugalmasságot tesz lehetővé a fent leírt megközelítéshez képest, mivel nagyon egyszerűvé teszi ugyanazt az attribútumot több helyen is újra felhasználni.
Tegyük fel, hogy egy tulajdonságot a relatív értéke alapján szeretnénk érvényesíteni az ugyanazon a nézetmodellben lévő másik tulajdonságra vonatkozóan. Az első lépés egy egyéni [GreaterThanAttribute]beállítás definiálása, például:
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");
}
}
Ezután hozzáadhatjuk ezt az attribútumot a nézetmodellhez:
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));
}
}
}
Ebben az esetben két numerikus tulajdonságunk van, amelyeknek egy adott tartományban kell lenniük, és egy adott kapcsolattal kell rendelkezniük egymás között (A nagyobbnak kell lennie, mint B). Hozzáadtuk az új [GreaterThanAttribute] elemet az első tulajdonság fölé, és egy ValidateProperty hívást is hozzáadtunk a B setteréhez, hogy a(z) A újra érvényesítésre kerüljön, valahányszor a(z) B megváltozik (mivel az érvényességi állapota ettől függ). Az egyéni érvényesítés engedélyezéséhez csak erre a két kódsorra van szükségünk a nézetmodellben, és egy újrafelhasználható egyéni érvényesítési attribútummal is rendelkezünk, amely az alkalmazás más nézetmodelljeiben is hasznos lehet. Ez a megközelítés a kód modularizálásában is segít, mivel az érvényesítési logika most már teljesen leválasztva van magáról a nézetmodell-definícióról.
Examples
- Tekintse meg a mintaalkalmazást (több felhasználói felületi keretrendszer esetén) az MVVM-eszközkészlet működés közbeni megtekintéséhez.
- Az egységtesztekben további példákat is találhat.