web-dev-qa-db-fra.com

Validation des données de formulaire WPF vraiment simple - comment faire?

Je vais avoir cette classe très simple, appelons-le client . Il ressemble à ceci:

namespace TestValidation
{
     class Customer
     {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                if (String.IsNullOrEmpty(value))
                {
                    throw new Exception("Customer name is mandatory.");
                }
            }
        }
    }
}

Maintenant, j'ai créé un formulaire de base, où l'utilisateur peut ajouter des clients à la base de données. Le formulaire contient une simple zone de texte, liée à la propriété Name de Customer et à un bouton "Ajouter".

Le code XAML est:

<Window x:Class="TestValidation.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestValidation"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
<TextBox Margin="119,86,107,194" Name="CustomerName"
        Text="{Binding Path=Customer.Name, 
                ValidatesOnExceptions=True, 
                ValidatesOnDataErrors=True,
                UpdateSourceTrigger=PropertyChanged,
                NotifyOnValidationError=True}"
    />
        <Button Content="Add" HorizontalAlignment="Left" Margin="204,176,0,0" VerticalAlignment="Top" Width="74"/>
    </Grid>
</Window> 

Vous devez comprendre que le nom est obligatoire pour moi de la part du créateur de la propriété Name. Je souhaite donc qu'un événement de validation augmente si la zone de texte Name est laissée vide. Selon les règles de validation de WPF - une fois que l'utilisateur se concentre sur le champ de texte et qu'il n'y a aucune valeur, il doit changer la couleur de la bordure en rouge. Pour une raison quelconque - cela ne se produit pas et je ne sais pas pourquoi. Quel est le problème dans mon processus?

Maintenant, j'ai lu beaucoup d'excellents articles sur la validation dans WPF (comme Application de règles de données d'entreprise complexes avec WPF , Validation des données dans WPF et validation dans Windows Presentation Foundation), mais aucun d'entre eux ne m'a aidé résoudre mon problème.

En fin de compte, je souhaite que le formulaire ressemble à celui de l'excellent article de Brian Noyes par rapport au premier lien (vous n'avez pas 10 crédits, je ne peux donc pas joindre une photo ... désolé).

Je serai reconnaissant si quelqu'un peut m'expliquer comment cela fonctionne vraiment.

Remarque importante - Je travaille avec .Net Framework 4, et j’ai donc besoin d’une solution adaptée à cette version.

19
Bak Itzik

Je recommanderais certainement d'utiliser IDataErrorInfo pour la validation WPF puisque WPF comprend déjà comment l'utiliser et qu'il est facile à implémenter.

Pour commencer, ajoutez l'interface à la classe contenant les données que vous souhaitez valider. Les méthodes requises ressembleront probablement à ceci:

public class Customer : IDataErrorInfo
{
    ...

    #region IDataErrorInfo Members

    string IDataErrorInfo.Error
    {
        get { return null; }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            if (columnName == "Name")
            {
                // Validate property and return a string if there is an error
                if (string.IsNullOrEmpty(Name))
                    return "Name is Required";
            }

            // If there's no error, null gets returned
            return null;
        }
    }
    #endregion
}

Ensuite, vous devez définir ValidatesOnDataErrors=True dans votre liaison TextBox pour qu'il exécute la validation chaque fois que la propriété Name change:

<TextBox Text="{Binding Path=Customer.Name, ValidatesOnDataErrors=True}" ... />

Et enfin, créez un modèle de validation dans votre XAML pour indiquer à WPF comment dessiner une erreur de validation. Voici le style/modèle que j'utilise habituellement:

<!-- ValidatingControl Style -->
<Style TargetType="{x:Type FrameworkElement}" x:Key="ValidatingControl">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="ToolTip" Value="{Binding 
                Path=(Validation.Errors)[0].ErrorContent, 
                RelativeSource={x:Static RelativeSource.Self}}" />
        </Trigger>
    </Style.Triggers>
</Style>

Assurez-vous également que votre classe Customer implémente INotifyPropertyChanged afin de répondre correctement aux mises à jour de l'interface utilisateur. Je ne vois pas cela dans votre code, mais souvent les gens laissent cela pour plus de simplicité :)

29
Rachel

Vous n'avez pas spécifié de règle de validation. La règle de validation est invoquée avant que le contrôle ne soit quitté et peut ensuite faire ce que vous voulez pour valider les entrées.

Un exemple simple - et je suppose que c'est ce que vous voulez faire - est fourni ici .

2
Thorsten Dittmar

Utilisez IDataErrorInfo pour la validation. ce lien vous aidera.

2
Sampath

Je pense que le problème peut être que votre classe n'implémente pas INotifyPropertyChanged, alors ne vous engagez pas comme prévu.

Implémentez l'interface INotifyPropertyChanged, déclenchez un événement lorsque la propriété a changé et que cela devrait fonctionner.

Voir http://msdn.Microsoft.com/en-us/library/ms743695(v=vs.110).aspx pour une procédure pas à pas.

0
Dave
<Binding Path=Name UpdateSourceTrigger="PropertyChanged">
  <Binding.ValidationRules>
    <ExceptionValidationRule />
  </Binding.ValidationRules>
</Binding>

http://msdn.Microsoft.com/en-us/library/ms752347%28v=vs.110%29.aspx#what_is_data_binding

S'il vous plaît utiliser ce blog: prasadcsharp.blogspot.com

0
user3510437

Je sais que ce post est vieux, mais voici quelque chose qui a bien fonctionné avec moi. Pas de latence ni de codage long mais je ne l'ai utilisé que sur des valeurs doubles. Vous pouvez le changer selon vos besoins.

 private void search_box_TextChanged(object sender, TextChangedEventArgs e)
    {
        //  box text and background to normal state if user types numbers
        search_box.Foreground = Brushes.Black;
        search_box.Background = Brushes.White;

          if (search_id.IsSelected == true)
        {
            try
            {
                //convert while user is typing
                if (string.IsNullOrEmpty(search_box.Text)==false)
              Convert.ToDouble(search_box.Text);
                search_error.Text = null;
            }

            //if user types a letter or a space or a symbol  ====>
            catch (Exception)
            {
          //  user cant type any value other than numbers as exception prevents it and clears the box text value <======
                search_box.Text = null;
                search_box.Foreground = Brushes.White;
                search_box.Background = Brushes.Red;
                search_error.Text="id is numberic value";
            }
        }

        }

J'espère que ça aide.

0
homa