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 :

[DataBinding] Problème sur un HelloWorld


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Par défaut [DataBinding] Problème sur un HelloWorld
    Bonjour tout le monde,

    j'essaye de me faire mon propre HelloWorld pour bien comprendre le dataBinding, mais j'ai un léger problème : le binding ne semble se faire qu'une seule fois, alors que je le spécifie bien en twoWay.

    J'ai suivi les recommandations sur les perf d'après ce lien. J'utilise donc des DependencyObject et DependencyProperty

    Voici ma classe de base :
    Code c# : 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
     
    public class DataSource : DependencyObject
        {
            public DataSource(String text)
            {
                Text = text;
            }
     
            public String Text
            {
                get { return (String)this.GetValue(TextProperty); }
                set { MessageBox.Show("tadam"); this.SetValue(TextProperty, value); }
            }
            public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
              "Text", typeof(String), typeof(DataSource), new PropertyMetadata(String.Empty));
        }
    Une bête classe qui contient une string... difficile de faire plus simple!

    Maintenant, je veux lier une instance de cette classe avec une textBox. (Note : oui, je sais, je pourrai faire la même chose avec OnEditChanged et monInstance.Text = maTextBox.Text, mais je veux comprendre le databinding pour l'appliquer ensuite à des cas beaucoup plus complexes)

    Dans ma fenetre, j'ai un membre de type DataSource
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private DataSource myDataSource = null;

    et dans le Init de la fentre, je fais :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    private void OnLoaded(object sender, RoutedEventArgs e)
            {
                myDataSource = new DataSource("TOTO");
     
                //Binding
                binding = new Binding("Text");
                binding.Source = myDataSource;
                binding.Mode = BindingMode.TwoWay;
                binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
     
                textBox1.SetBinding(TextBox.TextProperty, binding);
            }

    Lorsque la fenetre apparait, elle contient bien TOTO.

    Par contre, quand je modifie ma textBox, le texte de mon instance n'est pas modifié (j'ai mis un brkpoint sur le set).

    Qu'est ce qui ne va pas ?

    J'ai essayé aussi de faire le binding en XAML. Dans ce cas, en code behind, j'ai juste:
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    textBox1.DataContext = myDataSource;

    et dans mon xaml :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <TextBox.Text>
           <Binding Path="Text" UpdateSourceTrigger="PropertyChanged"></Binding>
    </TextBox.Text>

    Même résultat...

    Je pense que la solution est simple, mais je ne comprend pas d'où vient mon erreur. Est ce que quelqu'un a une idée lumineuse ? Merci!

  2. #2
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Salut ! Bonne idée de se mettre à WPF

    Citation Envoyé par rockeye Voir le message
    J'ai suivi les recommandations sur les perf d'après ce lien. J'utilise donc des DependencyObject et DependencyProperty
    Dans ta classe métier (contenant les données) tu n'as pas à implémenter tes propriétés sous forme de DependencyProperty. Et tes classes n'ont pas à hériter de dépendencyObject.

    DependencyProperty et dépendencyObject sont "réservés" aux éléments composant une présentation WPF (la présentation se distinguant des données présentées).

    Pour ta classe métier par contre, veille à implémenter l'interface INotifyPropertyChanged. L'infrastructure WPF saura détecter tout changement de valeur des propriétés CLR de ta classe métier et mettre à jour automatiquement l'affichage.

    Voilà pour commencer.

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Par défaut
    voici une exemple simple pour t'aider

    objet métier
    Code c# : 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
     
        public class Personne : INotifyPropertyChanged
        {
            #region INotifyPropertyChanged Members
            //----------------------------------------------------------------------------------
            public event PropertyChangedEventHandler PropertyChanged;
            //----------------------------------------------------------------------------------
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            //----------------------------------------------------------------------------------
            #endregion
           //----------------------------------------------------------------------------------
            #region Properties
            //----------------------------------------------------------------------------------
            private string _Nom = "";
            public string Nom
            {
                get { return _Nom; }
                set 
                { 
                    _Nom = value;
                    OnPropertyChanged("Nom");
                }
            }
     .....

    et pour le binding tu peux le faire en xaml direct
    en créant l'objet directement dans les ressources

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        xmlns:Local="clr-namespace:datatemplate_sur_tabitem"
        Title="Window1" Height="312" Width="775">
        <Window.Resources>
            <Local:Personne x:Name="Personne" x:Key="Personne" />
    tu remplacera le par :p avec le p majuscule


    et pour le binding
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DataContext="{Binding Source={StaticResource Personne}}" 
    ou
    Text="{Binding Source={StaticResource Personne}, Path=Nom}"

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Tu as indiqué ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    binding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
    Donc que l'objet métier sous-jacent doit etre ms à jour lorsque le contrôle graphique perd le focus: si tu saisis du texte et que tu appuies sur la touche Tabulation, tu devrais rentrer dans le Set de ta propriété.

  5. #5
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 38
    Par défaut
    @Fred.G :
    tu n'as pas à implémenter tes propriétés sous forme de DependencyProperty
    ben c'est pourtant ce qui est indiqué dans le lien que j'ai donné. Et Microsoft précise bien que la solution qui utilise INotifyPropertyChanged n'est pas la plus performante puisque ca utilise la réflexion, donc pas mal de ressources... Alors que les DependencyObject evite ca.

    @IKEAS : même remarque que pour Fred.G, et en plus, tu instancies un objet dans le XAML
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <Window.Resources>
            <Local:Personne x:Name="Personne" x:Key="Personne" />
    . Je vais peut-être dire une bêtise parce que je suis néophyte en xaml, mais ton objet est local à ta fenêtre. Dans quel type d'application est ce que ca peut bien servir ? Dans le cas où on te passe un objet en paramètre d'une méthode, comment tu fais ? Tu ne peux plus utiliser StaticResource...

    @Thomas Lebrun : effectivement, j'ai bien pensé à mettre 2 textbox dans ma fenêtre pour permettre le LostFocus.


    En fait, TOUT FONCTIONNE BIEN.
    Pour comprendre le fonctionnement, j'avais mis des beakpoints dans le set, en pensant que le binding passerait par le "set" pour modifier la valeur. Mais ce n'est pas le cas! Pour vérifier, il a suffit que je rajoute un bouton qui m'affiche la valeur de mon instance, et effectivement, ca correspond au text tapé dans la textbox.

    Donc pour fred.G et Ikeas, effectivement votre solution fonctionne, mais je vous conseille d'utiliser les DependencyObject, c'est plus performant (c'est pas moi qui le dis, mais crosoft!)

    Merci à tous pour votre aide!

  6. #6
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Un simple Hello Word et je plombe déjà les perfs avec mes conseils !

    Vous savez quoi ? Ben pour mes wrappeurs de la couche ViewModel je vais implémenter des DependencyProperty, na !

    Bien vu rockeye

  7. #7
    Membre émérite
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Par défaut
    Citation Envoyé par rockeye Voir le message
    En fait, TOUT FONCTIONNE BIEN.
    Petite question quand même... Est-ce que ta TextBox se met à jour quand la valeur de la propriété de ton objet source est modifiée par du code ?

    Maintenant que j'ai refait le test je crois me souvenir qu'à l'époque je n'avais pas obtenu ce rafraîchissement et c'est pour ça que je suis passé à INotifyPropertyChanged.
    Plus exactement, en xaml, tu déclares comment ton binding ?

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par rockeye Voir le message
    Donc pour fred.G et Ikeas, effectivement votre solution fonctionne, mais je vous conseille d'utiliser les DependencyObject, c'est plus performant (c'est pas moi qui le dis, mais crosoft!)
    Utiliser des DependencyProperty est p-e plus performant mais pas toujours possible. En effet, imagine que la classe sur laquelle tu désires implémenter ta DP hérite déjà de quelque chose: tu ne peux pas faire d'héritage multiple en .NET...
    De plus, cela nécessite de référence WindowBase.dll et ca, dans une assembly d'objet métier, ce n'est pas toujours souhaité/voulu de la part des développeurs/chef de projet, pour être le plus indépendant possible...

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

Discussions similaires

  1. Problème sur la recherche fulltext en v4 !
    Par poppa dans le forum Requêtes
    Réponses: 3
    Dernier message: 13/05/2004, 23h06
  2. Problème sur fiche MDIchild
    Par nivet dans le forum Composants VCL
    Réponses: 6
    Dernier message: 23/01/2004, 08h07
  3. Problème sur GetPrivateProfileString ???
    Par Bordelique dans le forum Langage
    Réponses: 7
    Dernier message: 25/06/2003, 22h15
  4. Problème sur une requête INSERT
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/06/2003, 08h45
  5. problème sur une requête!!!!!
    Par Mcgrady_01 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/06/2003, 01h17

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