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

C# Discussion :

MVVM et InvokeCommandAction


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut MVVM et InvokeCommandAction
    Salut à toutes et à tous,

    Soit un TextBox bindé à une variable.
    Soit le même TextBox sur lequel je veux utiliser d'event TextChanged.

    Le Xaml du TextBox
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            ...
            <TextBox Grid.Row="11" Grid.Column="1" Margin="5,5,0,5" Width="70" HorizontalAlignment="Left" Text="{Binding Decalage}" PreviewTextInput="TextBox_PreviewTextInput" x:Name="DecalageTBox">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="TextChanged">
                        <i:InvokeCommandAction Command="{Binding DecalageChangedCommand}" CommandParameter="{Binding Text, ElementName=DecalageTBox}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBox>
    La variable dans le ViewModel
    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
            private int _decalage;
            public int Decalage
            {
                get
                {
                    return _decalage;
                }
                set
                {
                    if (_decalage == value)
                        return;
                    _decalage = value;
                    RaisePropertyChanged(() => Decalage);
                }
            }
    Le code de l'Event
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public RelayCommand<string> DecalageChangedCommand { get; private set; }
              ...  
              DecalageChangedCommand = new RelayCommand<string>(
                    text =>
                    {
                        if (string.IsNullOrWhiteSpace(text))
                            Decalage = 0;
                        else
                            Decalage = Convert.ToInt32(text);
                    });
    Le problème :
    Au chargement le TextBox se bind bien (puisque "0", la valeur de départ, apparaît).
    Lorsque je modifie le Text du Texbox, l'EventTrigger passe très bien et Decalage est bien mis à jour.
    Par contre, si je modifie Decalage par le code, La variable est bien mise à jour, mais immédiatement après l'EventTrigger repasse et le text est toujours à la valeur écrite dans le TextBox. Le Decalage revient donc à la valeur précédente.

    Je ne comprend pas. Si l'EventTrigger relance DecalageChangedCommand , c'est bien que le text de la TextBox a changé. J'en déduis donc que le TextBox est mis à la valeur modifié par le code dans Décalage. Pourquoi l'EventTrigger déclanche DecalageChangedCommand alors que le text est le même ?
    Il me semble que lorsque Decalage change, le TextBox qui lui est bindé se met à jour. Je comprend dès lors que l'EventTrigger déclenche DecalageChangedCommand, mais le text devrait être le même que Decalage.

    Exemple :
    Démarrage : Decalage = 0 => TextBox.Text = "0"
    Utilisateur : modification de "0" par 20 : Decalage se met bien à 20.
    Code : Decalage = 30 : Decalage se met bien à 30. Immédiatement après, DecalageChangedCommand se déclenche et son text = "20". Decalage revient donc à 20. (C'est ici mon problème. Si DecalageChangedCommand déclenche, c'est à mon avis que TextBox.Text a dû changer, donc passer à 30. Pourquoi le text est-t-il à 20 ?)


    Qui peut m'expliquer ?
    Merci de vos z'avis z'avisés

  2. #2
    Membre expérimenté
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Septembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyste Programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 176
    Par défaut
    Bonjour,

    Je ne comprend pas trop ce que tu cherche à faire, mais ton approche ne me parait pas génial.

    Ce que je comprend de ton code, c'est que tu essaye de modifier la valeur de Decalage de 2 manières différentes en même temps.
    Une fois via le Binding, et une fois via l'EventTrigger.
    Il y a une raison précise à ça, ou j'ai raté quelque chose ?

    En l'état, je dirais que toute la partie de l'EventTrigger ne sert à rien.

    Bonne continuation.

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Salut et merci de t'intéresser a mon problème,
    Il semble que je me sois mal fait comprendre. Je ne cherche pas à le modifier de 2 manières différentes, au contraire.
    Le TextBox est bindé sur Decalage pour que le TextBox soit mis à jour quand Decalage change (binding "standard").
    J'ai aussi besoin d'une action sur l'event TextChanged (ne pas attendre de changer de champs).
    Jusque là ça fonctionne, la méthode roule.
    Parfois, à la fin de la méthode, Decalage doit être modifié (RAZ ou autre). Ce à quoi je m'attendais était que la méthode roule, Decalage est modifié, et par le binding le TextBox se met à jour.
    Dans la méthode, Decalage se met bien à jour (constaté par un break sur le set de la variable). Je suppose que le TextBox se met à jour puisque le TextChange est déclenché de nouveau (ce qui est logique puisque le TextBox a dû être mis à jour). Par contre c'est ici que mon problème se lève. Le texte retourné par <i:InvokeCommandAction Command="{Binding DecalageChangedCommand}" CommandParameter="{Binding Text, ElementName=DecalageTBox}" /> est le même qu'avant la MAJ (la valeur que l'utilisateur avait écrite. Pas celle mise à jour par le binding.

    Exemple :
    Decalage est à 0 => TextBox est à "0".
    l'utilisateur écrit "20" => l'Event TextChanged est levé et DecalageChangedCommand roule. Decalage est bien mis à jour sur 20.
    La méthode roule et Decalage est à nouveau modifié pour 30.
    Je suppose que TextBox est mis à jour par le binding puisque l'Event TextChanged est à nouveau levés, par contre le texte retourné par l'Event n'est pas 30 (ce qui serait logique puisque Decalage est à 30 et que TextBox a dû se mettre à jour via le binding), mais 20. C'est cela que je ne comprend pas.

    JM

  4. #4
    Membre expérimenté
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Septembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Analyste Programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 176
    Par défaut
    Bonjour,

    Effectivement, j'ai été un peu vite, si c'est le TextChanged qui t’intéresse, je renouvelle ma réponse précédente en ajoutant juste une petite chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Text="{Binding Decalage, UpdateSourceTrigger=PropertyChanged}"
    Dans ce cas, tu passera dans ton Set à chaque modification, comme pour un TextChanged.

    Bon, je ne connais pas réellement les EventTrigger et les InvokeCommandAction donc je ne vais pas trop m'avancer dessus (je n'en ai jamais eu besoin), par contre, utiliser un événement TextChanged sur un champs binder m'apparait comme un non sens.

    Bonne continuation.

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Bonjour et merci,

    Je ne connaissais pas le ", UpdateSourceTrigger=PropertyChanged" qui fait exactement ce dont j'ai besoin sans passer par les events.

    Encore merci,
    JM

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MVVM] Utilisation des InputBindings
    Par tomlev dans le forum Windows Presentation Foundation
    Réponses: 25
    Dernier message: 07/12/2009, 12h09
  2. MVVM : Listes et SelectedItems
    Par zax-tfh dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 22/03/2009, 00h05
  3. [MVVM] Colle du soir : MVVM et NavigationService
    Par zax-tfh dans le forum Windows Presentation Foundation
    Réponses: 23
    Dernier message: 19/03/2009, 10h44
  4. Command dans MVVM : un peu de mal à situer
    Par zax-tfh dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 15/03/2009, 13h45

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