J'ai un WPF UserControl avec de nombreux autres contrôles à l'intérieur. Les zones de texte sont parmi celles-ci. Chaque zone de texte a sa propre validation:
Validation.ClearInvalid(..) BindingExpression.UpdateTarget();
5 Réponses :
Pourquoi ne pas simplement déclencher notifypropertychangned pour toutes les propriétés de votre source de données? Cela mettra à jour la liaison et les contrôles d'interface utilisateur doivent obtenir des valeurs de DataContext (valides, donc des erreurs de validation seront effacées)? P>
Oh, je l'ai eu, cela fonctionne pour moi parce que j'utilise une option ValidatesExceptions et lancer des exceptions de validation dans Setters. Les valeurs si originales (valides) ne sont pas remplacées non valides.
Je ne suis pas sûr de ce que vous entendez par
Je fixe le DataContext dans le constructeur et je ne veux pas le changer (DataContext = null ne m'aidera pas alors) p> BlockQuote>
Généralement pour réinitialiser toutes les liaisons du formulaire que vous effectuez les suivantes: (en supposant un contrôleur pour le câblage de vues / viewModel, sinon utilisez simplement un code-derrière sur la vue. P>
var dataContext = view.DataContext; view.DataContext = null; view.DataContext = dataContext;
J'ai eu le même problème. Plusieurs contrôles validés sur une page. J'ai trouvé / fait cette solution pour mettre à jour (et effacer toute validation de) la descente d'une dépendanceObject:
using System.Linq; using System.Windows; using System.Windows.Data; using System.Windows.Media; /// <summary> /// Updates all binding targets where the data item is of the specified type. /// </summary> /// <param name="root">The root.</param> /// <param name="depth">The depth.</param> /// <param name="dataItemType">Type of the data item.</param> /// <param name="clearInvalid">Clear validation errors from binding.</param> public static void UpdateAllBindingTargets(this DependencyObject root, int depth, Type dataItemType, bool clearInvalid) { var bindingExpressions = EnumerateDescendentsBindingExpressions(root, depth); foreach (BindingExpression be in bindingExpressions.Where(be => be.DataItem != null && be.DataItem.GetType() == dataItemType)) { if (be != null) { be.UpdateTarget(); if (clearInvalid) System.Windows.Controls.Validation.ClearInvalid(be); } } } /// <summary> /// Enumerates all binding expressions on descendents. /// </summary> /// <param name="root">The root.</param> /// <param name="depth">The depth.</param> /// <returns></returns> public static IEnumerable<BindingExpression> EnumerateDescendentsBindingExpressions(this DependencyObject root, int depth) { return root.EnumerateDescendents(depth).SelectMany(obj => obj.EnumerateBindingExpressions()); } /// <summary> /// Enumerates the descendents of the specified root to the specified depth. /// </summary> /// <param name="root">The root.</param> /// <param name="depth">The depth.</param> public static IEnumerable<DependencyObject> EnumerateDescendents(this DependencyObject root, int depth) { int count = VisualTreeHelper.GetChildrenCount(root); for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(root, i); yield return child; if (depth > 0) { foreach (var descendent in EnumerateDescendents(child, --depth)) yield return descendent; } } } /// <summary> /// Enumerates the binding expressions of a Dependency Object. /// </summary> /// <param name="element">The parent element.</param> public static IEnumerable<BindingExpression> EnumerateBindingExpressions(this DependencyObject element) { if (element == null) { throw new ArgumentNullException("element"); } LocalValueEnumerator lve = element.GetLocalValueEnumerator(); while (lve.MoveNext()) { LocalValueEntry entry = lve.Current; if (BindingOperations.IsDataBound(element, entry.Property)) { if (entry.Value is PriorityBindingExpression) { foreach (BindingExpression expr in ((PriorityBindingExpression)entry.Value).BindingExpressions) yield return expr; } else if (entry.Value is MultiBindingExpression) { foreach (BindingExpression expr in ((MultiBindingExpression)entry.Value).BindingExpressions) yield return expr; } else yield return entry.Value as BindingExpression; } } }
C'est ce qu'est un groupe de contraignants pour ... vous définissez un groupe de liaison sur un conteneur de toutes les commandes, par ex. le panneau qui les contient. Cela entraînerait la tenue des mises à jour du DataContext jusqu'à ce que vous appeliez mises à jour sur le groupe de liaison. Si vous souhaitez réinitialiser l'entrée de l'utilisateur, vous appelleriez une annulation à la place, et le groupe de liaison réinitialiserait toutes les commandes à l'intérieur du conteneur sur les valeurs (toujours inchangées) du DataContext. p>
Bien que Hbarck a donné une réponse parfaitement correcte, je voudrais simplement ajouter cela pour de nombreux contrôles WPF standard, les groupes de liaison sont créé automatiquement. Par conséquent, dans la plupart des cas, le code simple suivant est suffisant pour éliminer toutes les erreurs de validation à l'intérieur de certains contrôles (par exemple, DataGrid):
foreach (var bg in BindingOperations.GetSourceUpdatingBindingGroups(myDataGrid)) bg.CancelEdit();
Lorsque vous liez les bonnes valeurs, alors elle réinitialisera automatiquement les erreurs de validation. Utilisez-vous INOTIFYPROPERTYCHANGED Interface sur votre viewModel & Property augmentera l'événement de la propriété?
Oui je l'utilise .. C'est ce que j'ai essayé au début. Mais il n'y a pas de changement dans la source de données. Par conséquent, WPF ne reflétera pas l'ancienne valeur