63 votes

Forcer la validation sur les contrôles liés dans WPF

J'ai un WPF dialogue avec un couple de zones de texte sur elle. Les zones de texte sont liés à mon objet de l'entreprise et ont WPF règles de validation ci-joint.

Le problème est que l'utilisateur peut parfaitement, cliquez sur " OK " et fermer la boîte de dialogue, sans réellement entrer les données dans les zones de texte. Les règles de Validation ne jamais faire feu, puisque l'utilisateur n'a même pas tenter d'entrer les informations dans les zones de texte.

Est-il possible de forcer des contrôles de validation et de déterminer si certaines règles de validation sont cassé?

Je serais capable de le faire lorsque l'utilisateur tente de fermer la boîte de dialogue et de lui interdire de le faire si les règles de validation sont cassés.

Je vous remercie.

75voto

Ken Smith Points 9165

En 3.5SP1 / 3.0SP2, ils ont également ajouté une nouvelle propriété à la Règle de base, à savoir, ValidatesOnTargetUpdated="True". Ce qui fera appel à la validation dès que l'objet source est lié, plutôt que de seulement lorsque la cible de contrôle est mis à jour. Qui peut ne pas être exactement ce que vous voulez, mais c'est pas mal pour voir tous les trucs que vous devez corriger.

Fonctionne quelque chose comme ceci:

<TextBox.Text>
    <Binding Path="Amount" StringFormat="C">
        <Binding.ValidationRules>
            <validation:RequiredValidationRule 
                ErrorMessage="The pledge amount is required." 
                ValidatesOnTargetUpdated="True"  />
            <validation:IsNumericValidationRule 
                ErrorMessage="The pledge amount must be numeric." 
                ValidationStep="ConvertedProposedValue" 
                ValidatesOnTargetUpdated="True"  />
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>

67voto

Robert Macnee Points 6998

Nous avons ce problème dans notre application. La validation se déclenche uniquement lorsque les liaisons de mise à jour, donc vous devez les mettre à jour à la main. Nous faisons cela dans la Fenêtre de Chargement de l'événement:

public void Window_Loaded(object sender, RoutedEventArgs e)
{
    // we manually fire the bindings so we get the validation initially
    txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    txtCode.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}

Cela va faire l'erreur de modèle (contour rouge) apparaissent, et l'ensemble de Validation.HasError de la propriété, que nous avons déclencher le bouton OK pour désactiver:

<Button x:Name="btnOK" Content="OK" IsDefault="True" Click="btnOK_Click">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="IsEnabled" Value="false" />
            <Style.Triggers>
                <!-- Require the controls to be valid in order to press OK -->
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=txtName, Path=(Validation.HasError)}" Value="false" />
                        <Condition Binding="{Binding ElementName=txtCode, Path=(Validation.HasError)}" Value="false" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="true" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

0voto

Alex Pollan Points 216

Utilisez la méthode ci-dessus proposée par Robert Macnee. Par exemple:

 //force initial validation
foreach (FrameworkElement item in grid1.Children)
{
    if (item is TextBox)
    {
        TextBox txt = item as TextBox;
        txt.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }
}        
 

Mais, ASSUREZ-VOUS que les contrôles liés sont visibles avant que ce code ne soit exécuté!

-3voto

Jenzo Points 1

Utilisation de INotifyPropertychanged sur votre objet de données

 public class MyObject : INotifyPropertyChanged
{
    string _MyPropertyToBind = string.Empty;
    public string MyPropertyToBind
    {
        get
        {
            return _MyPropertyToBind;
        }
        set
        {
            _MyPropertyToBind = value;
            NotifyPropertyChanged("MyPropertyToBind");
        }
    }

    public void NotifyPropertyChanged(string property)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

}
 

vous pouvez ajouter le code suivant à votre commande

 <TextBox Text="{Binding MyPropertyToBind, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
 

La zone de texte souscrit à l'événement propertychanged de l'objet datacontext (MyObjet dans notre exemple) et suppose qu'elle est déclenchée lorsque les données source ont été mises à jour.

il force automatiquement l'actualisation au contrôle

Pas besoin de vous appeler la méthode UpdateTarget

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X