Utiliser les règles de Validation WPF et désactiver le bouton "Enregistrer"
j'ai une page où quelques boîtes de texte ne peuvent pas être vides avant de cliquer sur un bouton Enregistrer.
<TextBox...
<TextBox.Text>
<Binding Path ="LastName" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:StringRequiredValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
Ma règle fonctionne. J'ai une bordure rouge autour de ma boîte de texte jusqu'à ce que j'entre une valeur. Donc maintenant je veux ajouter cette règle de validation à mes autres zones de texte.
maintenant, comment désactiver le bouton Enregistrer jusqu'à ce que la page n'ait aucune erreur? Je ne sais pas quoi vérifier pour voir si il y a des erreurs de validation.
8 réponses
Voici l'échantillon que vous avez besoin.
http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/
https://skydrive.live.com/?cid=2c6600f1c1d5e3be&id=2C6600F1C1D5E3BE%21203
sur le codebehind pour la vue, vous pouvez ajouter la validation.ErrorEvent comme suit:
this.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(OnErrorEvent));
Et
private int errorCount;
private void OnErrorEvent(object sender, RoutedEventArgs e)
{
var validationEventArgs = e as ValidationErrorEventArgs;
if (validationEventArgs == null)
throw new Exception("Unexpected event args");
switch(validationEventArgs.Action)
{
case ValidationErrorEventAction.Added:
{
errorCount++; break;
}
case ValidationErrorEventAction.Removed:
{
errorCount--; break;
}
default:
{
throw new Exception("Unknown action");
}
}
Save.IsEnabled = errorCount == 0;
}
ceci fait l'hypothèse que vous recevrez un avis de suppression (ce qui n'arrivera pas si vous supprimez l'élément offensant pendant qu'il est invalide).
Vous souhaitez utiliser Validation.HasError propriété attachée.
dans le même ordre d'idées, Josh Smith a une lecture intéressante sur Liaison d' (Validation.Erreurs)[0] sans créer Debug Spew.
int count = 0;
private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
if (e.Action == ValidationErrorEventAction.Added)
{
button1.IsEnabled = false;
count++;
}
if (e.Action == ValidationErrorEventAction.Removed)
{
count--;
if (count == 0) button1.IsEnabled = true;
}
}
Voici une méthode helper qui trace les erreurs de validation sur les objets de dépendances (et tous ses enfants) et appelle delegate pour notifier le changement. Il suit également l'enlèvement des enfants avec des erreurs de validation.
public static void AddErrorHandler(DependencyObject element, Action<bool> setHasValidationErrors)
{
var errors = new List<Tuple<object, ValidationError>>();
RoutedEventHandler sourceUnloaded = null;
sourceUnloaded = (sender, args) =>
{
if (sender is FrameworkElement)
((FrameworkElement) sender).Unloaded -= sourceUnloaded;
else
((FrameworkContentElement) sender).Unloaded -= sourceUnloaded;
foreach (var error in errors.Where(err => err.Item1 == sender).ToArray())
errors.Remove(error);
setHasValidationErrors(errors.Any());
};
EventHandler<ValidationErrorEventArgs> errorHandler = (_, args) =>
{
if (args.Action == ValidationErrorEventAction.Added)
{
errors.Add(new Tuple<object, ValidationError>(args.OriginalSource, args.Error));
if (args.OriginalSource is FrameworkElement)
((FrameworkElement)args.OriginalSource).Unloaded += sourceUnloaded;
else if (args.OriginalSource is FrameworkContentElement)
((FrameworkContentElement)args.OriginalSource).Unloaded += sourceUnloaded;
}
else
{
var error = errors
.FirstOrDefault(err => err.Item1 == args.OriginalSource && err.Item2 == args.Error);
if (error != null)
errors.Remove(error);
}
setHasValidationErrors(errors.Any());
};
System.Windows.Controls.Validation.AddErrorHandler(element, errorHandler);
}
c'est ça vous devez vérifier la propriété de contrôle HasError à partir du code behaind
et faire ce code dans le bouton enregistrer, cliquez sur
BindingExpression bexp = this.TextBox1.GetBindingExpression(TextBox.TextProperty);
bexp.UpdateSource(); // this to refresh the binding and see if any error exist
bool hasError = bexp.HasError; // this is boolean property indique if there is error
MessageBox.Show(hasError.ToString());
il suffit d'insérer votre modèle de vue du système.ComponentModel.IDataErrorInfo pour valider et de INotifyPropertyChanged pour notifier le bouton
faire de la propriété:
public bool IsValid
{
get
{
if (this.FloorPlanName.IsEmpty())
return false;
return true;
}
}
dans le code xaml, le connecter à bouton
<Button Margin="4,0,0,0" Style="{StaticResource McVMStdButton_Ok}" Click="btnDialogOk_Click" IsEnabled="{Binding IsValid}"/>
dans les dérogations IDataErrorInfo, notifiez btutton
public string this[string columnName]{
get
{
switch (columnName)
{
case "FloorPlanName":
if (this.FloorPlanName.IsEmpty())
{
OnPropertyChanged("IsValid");
return "Floor plan name cant be empty";
}
break;
}
}
}
j'ai essayé plusieurs des solutions mentionnées ci-dessus; cependant, aucune d'entre elles n'a fonctionné pour moi.
Mon Problème Simple
j'ai une fenêtre de saisie simple qui demande un URI de l'utilisateur, si le TextBox
valeur n'est pas valide Uri
puis Okay
bouton doit être désactivé.
Ma Solution Simple
Voici ce qui a fonctionné pour moi:
CommandBindings.Add(new CommandBinding(AppCommands.Okay,
(sender, args) => DialogResult = true,
(sender, args) => args.CanExecute = !(bool) _uriTextBoxControl.GetValue(Validation.HasErrorProperty)));