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

Silverlight Discussion :

Problème de Binding


Sujet :

Silverlight

  1. #1
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut Problème de Binding
    Bonjour à tous, je me remet tranquillement au DataBinding (en Silverlight 4) en essayant de faire un petit truc tout simple mais je bloque.

    Alors j'ai une classe personne qui ressemble à ça :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    public class Personne :INotifyPropertyChanged
        {
            public static ObservableCollection<Personne> ListPersonnes = new ObservableCollection<Personne>();
     
            private string _Nom;
            public string Nom
            {
                get
                {
                    return this._Nom;
                }
                set
                {
                    this._Nom = value;
                    OnPropertyChanged("Nom");
                }
            }
     
            private string _Prenom;
            public string Prenom
            {
                get
                {
                    return this._Prenom;
                }
                set
                {
                    this._Prenom = value;
                    OnPropertyChanged("Prenom");
                }
            }
     
     
            private DateTime _DateDeNaissance;
            public DateTime DateDeNaissance
            {
                get
                {
                    return this._DateDeNaissance;
                }
                set
                {
                    this._DateDeNaissance = value;
                }
            }
     
            public Personne(string _LeNom,string _LePrenom,DateTime _LaDate)
            {
                this.Nom = _LeNom;
                this.Prenom = _LePrenom;
                this._DateDeNaissance = _LaDate;
     
                ListPersonnes.Add(this);
            }
            public Personne()
            {
     
            }
     
            public override string ToString()
            {
                return this.Nom + ' ' + this.Prenom;
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propName)
            {
                PropertyChangedEventHandler eh = this.PropertyChanged;
                if (null != eh)
                {
                    eh(this, new PropertyChangedEventArgs(propName));
                }
            }
     
        }
    Ensuite dans mon interface j'ai juste une ComboBox que remplie à l'aide de ma static ObservableCollection<Personne> ListPersonnes. Puis j'aimerais qu'en fonction de la selection, le détail de ma personne s'affiche dans un formulaire à côté. j'ai donc procédé comme cela :

    Main.xaml.cs :
    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
    public partial class MainPage : UserControl
        {
     
            public Personne SelectedPersonne { get; set; }
     
            public MainPage()
            {
                InitializeComponent();
     
                SelectedPersonne = new Personne();
     
                Personne Personne1 = new Personne("Reagan", "Ronald", new DateTime(1911, 02, 06));
                Personne Personne2 = new Personne("Mitterrand", "François", new DateTime(1916, 09, 26));
                Personne Personne3 = new Personne("Marx", "Karl", new DateTime(1818, 05, 05));
                Personne Personne4 = new Personne("Zedong", "Mao", new DateTime(1893, 12, 26));
                Personne Personne5 = new Personne("Guevara", "Ernesto", new DateTime(1928, 06, 14));
     
                Cb_Personnes.ItemsSource = Personne.ListPersonnes;
            }
     
        }
    et mon Main.xaml :
    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
    <Grid x:Name="LayoutRoot" Background="White" Height="300" Width="400" >
            <Grid.RowDefinitions>
                <RowDefinition Height="150"></RowDefinition>
                <RowDefinition Height="30"></RowDefinition>
                <RowDefinition Height="30"></RowDefinition>
            </Grid.RowDefinitions>
     
            <Grid x:Name="GridPersonne" Grid.Row="0" DataContext="{Binding SelectedPersonne,Mode=TwoWay}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50*"></ColumnDefinition>
                    <ColumnDefinition Width="50*"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="35"></RowDefinition>
                    <RowDefinition Height="35"></RowDefinition>
                    <RowDefinition Height="35"></RowDefinition>
                    <RowDefinition Height="35"></RowDefinition>
                    <RowDefinition Height="35"></RowDefinition>
                    <RowDefinition Height="35"></RowDefinition>
                </Grid.RowDefinitions>
     
                <!--Les labels-->
                <TextBlock Text="Nom : " Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right"></TextBlock>
                <TextBlock Text="Prenom : " Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right"></TextBlock>
                <TextBlock Text="Date de Naissance : " Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right"></TextBlock>
     
                <!--les composants que l'on va Binder-->
                <TextBox Name="Tb_Nom" Grid.Column="1" Grid.Row="0" Text="{Binding Nom,Mode=TwoWay}"></TextBox>
                <TextBox Name="Tb_Prenom" Grid.Column="1" Grid.Row="1" Text="{Binding Prenom,Mode=TwoWay}"></TextBox>
                <sdk:DatePicker Name="Dp_Date" Grid.Column="1" Grid.Row="2" SelectedDate="{Binding DateDeNaissance,Mode=TwoWay}"/>
            </Grid>
            <TextBlock Text="Liste des personnes : " Grid.Row="1"></TextBlock>
            <ComboBox Name="Cb_Personnes" Grid.Row="2" SelectedItem="{Binding SelectedPersonne,Mode=TwoWay}"></ComboBox>
     
        </Grid>
    Déja mon Objet SelectedPersonne ne s'update pas lors d'un changement de selection de ma comboBox.
    Si je rajoute à la main sur l'evenement SelectionChanged de ma comboBox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Cb_Personnes.SelectionChanged += (o, e) =>
                {
                    var r = o as ComboBox;
                    SelectedPersonne = r.SelectedItem as Personne;                
                };
    Et que j'enlève le binding de SelectedItem de ma comboBox, cela n'update toujours pas mon formulaire je suis obliger de rajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Cb_Personnes.SelectionChanged += (o, e) =>
                {
                    var r = o as ComboBox;
                    SelectedPersonne = r.SelectedItem as Personne;
                    LayoutRoot.DataContext = SelectedPersonne;
                };
    Mais je ne trouve pas ça très propre, je crois que j'ai raté quelque chose mais je ne vois pas quoi.

    Cordialement MoZo

  2. #2
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Bonjour,

    Déja mon Objet SelectedPersonne ne s'update pas lors d'un changement de selection de ma comboBox
    N'oublie pas ce que représente l'objet que tu bindes. C'est à dire lorsque que tu fais un Binding de SelectedPersonne qu'elle est l'objet parent en cause (qu'elle est le DataContext ?).

    Si tu veux que ce soit ton contrôle MainPage (qui contient SelectedPersonne) il faut lui spécifié. Par exemple dans le constructeur de ta page :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public MainPage()
            {
                InitializeComponent();
                // On redirige le control vers le DataContext
                this.LayoutRoot.DataContext = this;
                // ton code...
            }
    Pour que SelectedControl notifie ses changements à l'UI, il vaudrait mieux que tu la passe en propdp.

  3. #3
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut
    Merci à toi Samoteph !!

    Alors les depencyProperty c'est un truc que je connaissais/utilisais pas

    En suivant tes conseil j'ai donc fait :

    Dans le Main.cs :
    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
    public Personne SelectedPersonne
            {
                get { return (Personne)GetValue(SelectedPersonneProperty); }
                set { SetValue(SelectedPersonneProperty, value); }
            }
     
            // Using a DependencyProperty as the backing store for SelectedPersonne.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty SelectedPersonneProperty =
                DependencyProperty.Register("SelectedPersonne", typeof(Personne), typeof(MainPage), new PropertyMetadata(MyPropertyChanged));
     
            static void MyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
            {
     
            }
     
            public MainPage()
            {
                InitializeComponent();
     
                this.LayoutRoot.DataContext = this;
     
                //On créer des personnes au hazard
                Personne Personne1 = new Personne("Reagan", "Ronald", new DateTime(1911, 02, 06));
                Personne Personne2 = new Personne("Mitterrand", "François", new DateTime(1916, 09, 26));
                Personne Personne3 = new Personne("Marx", "Karl", new DateTime(1818, 05, 05));
                Personne Personne4 = new Personne("Zedong", "Mao", new DateTime(1893, 12, 26));
                Personne Personne5 = new Personne("Guevara", "Ernesto", new DateTime(1928, 06, 14));
     
                Cb_Personnes.ItemsSource = Personne.ListPersonnes;
                Cb_MeilleurPotes.ItemsSource = Personne.ListPersonnes;
            }
    Et la ça marche parfaitement. Si je peux me permettre de demander une précision: dans le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new UIPropertyMetadata(0));
    Qu'est ce que je doit mettre exactement dans le type ownerClass ?? Forcement le UserControl qui contient la propriété ?

    Sinon lorsque je modifie les noms de mes personnes cela est bien enregistré dans les objet mais l'affichage des noms n'est pas répercuté sur la comboBox Comment pour que si par exemple je modifie le nom de François, par Pierre, et bien j'ai Pierre Mitterrand qui s'affiche dans ma comboBox ??

    Encore Merci Cordialement MoZo

  4. #4
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Qu'est ce que je doit mettre exactement dans le type ownerClass ?? Forcement le UserControl qui contient la propriété ?
    Oui forcément.

    Sinon lorsque je modifie les noms de mes personnes cela est bien enregistré dans les objet mais l'affichage des noms n'est pas répercuté sur la comboBox Comment pour que si par exemple je modifie le nom de François, par Pierre, et bien j'ai Pierre Mitterrand qui s'affiche dans ma comboBox ??
    Ta classe personne est bien un INotypropertyChanged donc elle devrait bien propager ses changements.
    Tente de sortir la liste statique de personne de la classe personne pour en faire une instance car je ne suis pas persuadé que le Binding fonctionne correctement en Silverlight avec des variables statics.
    profite-en pour virer la ligne d'ajout automatique de la personne dans la liste à l'intérieur du constructeur, car c'est mal

  5. #5
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut
    profite-en pour virer la ligne d'ajout automatique de la personne dans la liste à l'intérieur du constructeur, car c'est mal
    Tu parles de l'ajout à ma liste static dans le construteur de ma classe Personne ?? Ok je l'enleve mais je pourrais savoir pourquoi c'est mal ??

    Sinon pour le Bind sur une variable static j'ai vu aussi que ça ne fonctionnait pas bien donc j'ai créer une ObservableCollection dans ma classe Main que je remplie dans le constructeur de cette dernière.

    Sinon pour ma ComboBox en fait le changement est bien répercuté mais seulement lorsque la ligne est selectionné, c'est un peu dure à expliquer donc je met une petite photo :

  6. #6
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    Tu parles de l'ajout à ma liste static dans le construteur de ma classe Personne ?? Ok je l'enleve mais je pourrais savoir pourquoi c'est mal ??
    car quelqu'un qui instancie ta classe et qui ne connait pas ton code (ou qui ne s'en souvient plus) ne s'attend par lorsqu'il instancie un objet à l'avoir ajouté automatiquement dans une liste. Tes méthodes doivent faire ce qu'indique leur nom sinon c'est rapidement le b****l Par exemple un constructeur c'est fait pour initialiser et pas pour ajouter dans une liste.

    Pour la mise à jour de ta ComboBox, essaye d'ajouter dans ta liste une personne fictive et de la retirer de suite afin que la liste se rafraîchisse.

  7. #7
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut
    car quelqu'un qui instancie ta classe et qui ne connait pas ton code (ou qui ne s'en souvient plus) ne s'attend par lorsqu'il instancie un objet à l'avoir ajouté automatiquement dans une liste. Tes méthodes doivent faire ce qu'indique leur nom sinon c'est rapidement le b****l Par exemple un constructeur c'est fait pour initialiser et pas pour ajouter dans une liste.
    OK je prend note

    Sinon ajouter et retirer ensuite une personne fictive ne change rien mes changements sont bien pris en compte mais pas affichés lorsque la ComboBox est déroulé (cf la photo de mon post précédent)

    Encore merci à toi !!

  8. #8
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    sinon, en prenant le problème à l'envers, tu peux forcer la dropdownlist à se fermer (via IsDropDownOpen) dès que tu ecris dans les textboxs

  9. #9
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut
    sinon, en prenant le problème à l'envers, tu peux forcer la dropdownlist à se fermer (via IsDropDownOpen) dès que tu ecris dans les textboxs
    Ça n'arrange pas vraiment mon problème car Imaginons que je change mon Francois Mitterand en Jacques Chirac.

    Et bien si je veux sélectionner à nouveau Jacques dans la liste, il faut que je click sur Francois Mitterand dans la liste de ma ComboBox qui une fois selectionné s'affiche bien Jacques Chirac (lorsque la liste de la ComboBox se referme)

    Je sais pas si je me fais comprendre en fait

  10. #10
    Membre Expert
    Avatar de Samuel Blanchard
    Homme Profil pro
    Expert .NET
    Inscrit en
    Février 2010
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Expert .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 1 504
    Par défaut
    alors tu peux retirer la Personne de la liste que tu viens de modifier (en conservant son index) puis la rajouter (avec l'index)

  11. #11
    Membre éclairé Avatar de Mozofeuk
    Inscrit en
    Novembre 2007
    Messages
    326
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 326
    Par défaut
    Bon j'ai résolu le problème en faisant comme tu proposais, ça marche mais je trouve ça pas très propre quand même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    this.Cb_Personnes.DropDownClosed += (o, e) => {
                    int a = Cb_Personnes.SelectedIndex;
                    var b = SelectedPersonne;
     
                    ListePersonnes.RemoveAt(a);
                    ListePersonnes.Insert(a, b);
     
                    SelectedPersonne = b;
                };
    J'ai mis ça sur le DropDownClosed car sinon je levé une exception si je mettais ça sur le SelectionChanged.

    Voila merci pour ton aide Samoteph !!

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

Discussions similaires

  1. [WPF] Probléme de binding dans un UserControl :(
    Par UNi[FR] dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 17/07/2008, 15h51
  2. Probléme avec Bind
    Par rach20032 dans le forum Réseau
    Réponses: 2
    Dernier message: 06/07/2007, 11h36
  3. [Netbeans 6M9 JDk6.1 Matisse] problème de binding
    Par tralloc dans le forum NetBeans
    Réponses: 14
    Dernier message: 21/06/2007, 13h32
  4. problème de bindings avec DropDownList
    Par Vlatiska dans le forum ASP.NET
    Réponses: 14
    Dernier message: 17/03/2007, 14h04
  5. [C#][MySQL 5.x]Problème de Binding
    Par Oufti dans le forum Windows Forms
    Réponses: 2
    Dernier message: 07/05/2006, 23h44

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