IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Comment créer une classe de validation avec un paramètre?


Sujet :

Windows Presentation Foundation

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 97
    Points : 106
    Points
    106
    Par défaut Comment créer une classe de validation avec un paramètre?
    Bonjour à tous,

    Voici mon souci : je souhaite créer une classe héritant de ValidationRule et qui utiliserait un paramètre.

    Voici le contexte. Dans l'application, l'utilisateur peut saisir des entiers. Seulement, ces entiers ne doivent pas être supérieurs à borne limite qui est issue d'un fichier de configuration.

    Par exemple, dans mon fichier de configuration, je mets la limite à 150. Je lance l'application, je ne dois pas pouvoir saisir des entiers supérieurs à 150.
    Je modifie mon fichier en mettant la limite à 100. En relaçant mon application, je ne devrais pas pouvoir saisir des entiers supérieurs à 100.

    J'utilise la méthodologie MVVM.

    J'ai fait quelques recherches sur internet et j'ai trouvé ceci :

    http://www.codeproject.com/KB/WPF/At...select=2110158

    Ca a l'air assez usine à gaz mais le principe fonctionne.

    Mon souci est que dans la view, l'auteur définit le DataContext :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <UserControl.DataContext>
      <Binding Mode="OneWayToSource" Path="DataContext" Source="{StaticResource DataContextBridge}" />
    </UserControl.DataContext>
    Or, moi je veux récupérer ma limite dans mon vue-modèle.

    Pour ce faire, je fais un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <Test:IntegerContainer DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LimitInVM}"  />
    Du coup, ca va chercher LimitInVM dans le DataContext défini et non dans mon VM.

    Quelqu'un aurait-il une astuce pour aller chercher LimitInVM dans le "bon" DataContext?

    Merci, Cécile.

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    J'ai rien compris: tu peux réexpliquer ?

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 97
    Points : 106
    Points
    106
    Par défaut
    Bonjour,

    C'est un problème un peu complexe, je vais essayer d'être plus claire.

    Au niveau de l'IHM, il y a un TextBox dans lequel l'utilisateur doit saisir un entier.

    Or, pour être valide, cet entier ne doit pas dépasser une certaine limite. Mais cette limite varie, ce n'est pas une constante.

    Donc, pour contrôler l'entier saisi par l'utilisateur, je souhaiterais créer une classe qui hériterait de ValidationRule et qui prendrait en paramètre la limite à ne pas dépasser.

    J'ai donc cherché une solution sur internet et j'ai trouvé une méthode qui avait l'air pas mal :
    http://www.codeproject.com/KB/WPF/At...select=2110158

    J'ai créé la classe IntegerContainer, héritant de FrameworkElement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class IntegerContainer : FrameworkElement
        {
            public int Value
            {
                get { return (int)GetValue(ValueProperty); }
                set { SetValue(ValueProperty, value); }
            }
     
            public static readonly DependencyProperty ValueProperty =
             DependencyProperty.Register("Value", typeof(int), typeof(IntegerContainer), new UIPropertyMetadata(0));
        }
    Puis, j'ai créé ma classe de validation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class IntegerValidationRule : ValidationRule
        {
            public IntegerContainer Limit { get; set; }
     
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            {
                var intValue = (int)value;
                if (intValue > Limit.Value)
                {
                    return new ValidationResult(false, null);
                }
     
                return new ValidationResult(true, null);
            }
        }
    J'ai modifié ma vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <UserControl x:Class="WpfApplication1.UserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfApplication1="clr-namespace:WpfApplication1">
     
        <UserControl.Resources>
            <FrameworkElement x:Key="DataContextBridge" />
        </UserControl.Resources>
     
        <UserControl.DataContext>
            <Binding Mode="OneWayToSource" Path="DataContext" Source="{StaticResource DataContextBridge}" />
        </UserControl.DataContext>
     
        <Grid>
     
            <ListView ItemsSource="{Binding PolarPoints}" SelectedItem="{Binding SelectedPolarPoint}" IsSynchronizedWithCurrentItem="True">
                <ListView.View>
                    <GridView>
                        <GridViewColumn>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBox>
                                        <Binding Path="ValueInKnot">
                                            <Binding.ValidationRules>
                                                <WpfApplication1:IntegerValidationRule>
                                                    <WpfApplication1:IntegerValidationRule.Limit>
                                                        <WpfApplication1:IntegerContainer DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LimitInVM}"  />
                                                    </WpfApplication1:IntegerValidationRule.Limit>
                                                </WpfApplication1:IntegerValidationRule>
                                            </Binding.ValidationRules>
                                        </Binding>
                                    </TextBox>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>                    
                    </GridView>
                </ListView.View>
            </ListView>
     
        </Grid>
    </UserControl>
    Dans mon vue-model, j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public int LimitInVM { get; set; }
    Le souci, c'est dans le code xaml, lorsque je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <WpfApplication1:IntegerContainer DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.LimitInVM}" />
    la valeur de LimitInVM est recherchée dans le DataContext spécifié, c'est-à-dire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <UserControl.DataContext>
            <Binding Mode="OneWayToSource" Path="DataContext" Source="{StaticResource DataContextBridge}" />
    </UserControl.DataContext>
    et non dans mon vue-modèle.

    J'aimerais donc savoir s'il existe une astuce pour que l'application n'aille pas chercher dans le DataContext défini dans le xaml mais plutôt dans mon vue-modèle.

    J'espère que c'est plus clair.

    Cécile.

Discussions similaires

  1. Réponses: 5
    Dernier message: 17/07/2006, 18h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo