ValidationRule pour appliquer un nom unique
-
09-06-2019 - |
Question
J'essaie d'écrire une ValidationRule WPF personnalisée pour faire en sorte qu'une certaine propriété soit unique dans le contexte d'une collection donnée.Par exemple:Je modifie une collection d'objets personnalisés liés à un ListView et je dois m'assurer que la propriété Name de chaque objet de la collection est unique.Est-ce que quelqu'un sait comment faire ça?
La solution
Tout d’abord, je créerais une simple classe DependencyObject pour contenir votre collection :
class YourCollectionType : DependencyObject {
[PROPERTY DEPENDENCY OF ObservableCollection<YourType> NAMED: BoundList]
}
Ensuite, sur votre classe dérivée de ValidationRule, créez une propriété :
YourCollectionType ListToCheck { get; set; }
Ensuite, dans le XAML, faites ceci :
<Binding.ValidationRules>
<YourValidationRule>
<YourValidationRule.ListToCheck>
<YourCollectionType BoundList="{Binding Path=TheCollectionYouWantToCheck}" />
</YourValidationRule.ListToCheck>
</YourValidationRule>
</Binding.ValidationRules>
Ensuite, lors de votre validation, examinez la collection de la propriété BoundList de ListToCheck pour l'élément que vous validez.S'il est là, renvoie évidemment un faux résultat de validation.Si ce n'est pas le cas, retournez vrai.
Autres conseils
Je ne créerais un objet de dépendance personnalisé que s'il y avait d'autres propriétés que je souhaitais lier à la règle.Puisque dans ce cas, tout ce que nous faisons est d'attacher une seule collection de valeurs à vérifier, j'ai fait mon <UniqueValueValidationRule.OtherValues>
propriété un <CollectionContainer>
.
A partir de là, pour dépasser le problème du DataContext
n'étant pas hérité, <TextBox.Resources>
il fallait avoir un <CollectionViewSource>
pour tenir la reliure réelle et lui donner un {StaticResource}
clé, qui OtherValues
pourrait alors utiliser comme source de liaison.
La règle de validation elle-même n'a alors besoin que d'une boucle OtherValues.Collection
et effectuer des contrôles d’égalité.
Observer:
<TextBox>
<TextBox.Resources>
<CollectionViewSource x:Key="otherNames" Source="{Binding OtherNames}"/>
</TextBox.Resources>
<TextBox.Text>
<Binding Path="Name">
<Binding.ValidationRules>
<t:UniqueValueValidationRule>
<t:UniqueValueValidationRule.OtherValues>
<CollectionContainer Collection="{Binding Source={StaticResource otherNames}}"/>
</t:UniqueValueValidationRule.OtherValues>
</t:UniqueValueValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>