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 :

Problème définition d'un Binding


Sujet :

Windows Presentation Foundation

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut Problème définition d'un Binding
    Bonjour,
    Décidément, les Bindings me causent bien des soucis en ce moment...
    Voici le problème :
    J'ai une classe Membre avec 1 propriété Ville qui est elle-même un objet Ville comportant les 3 propriétés suivantes : ID, Nom, CodePostal. De sorte que pour accéder au nom de la ville d'un membre, je fais : MonMembre.Ville.Nom
    J'ai créé une Textbox CodePostal bindée à la propriété Ville.CodePostal de mon objet Membre. J'ai aussi créé une Combobox Ville et là, le binding me pose problème. Tant que la textbox CodePostal est vide, je veux que la Combobox soit désactivée (ça, c'est ok). Dès que la textbox CodePostal atteint 5 caractères, je veux que la combobox liste toutes les villes ayant ce code postal (c'est aussi ok, je l'ai bindé à une DataView qui contient la liste des villes). Le DataContext de la combo Ville se retrouve donc défini sur cette DataView, seulement, je veux que la propriété SelectedItem soit bindée à la propriété Ville.ID de mon objet Membre (donc un DataContext différent).
    Voici le code Xaml pour la textbox CodePostal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <TextBox Text="{Binding Mode=TwoWay, Path=Ville.CodePostal}" />
    Et pour la combobox Ville :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=Ville.Nom}" SelectedValue="{Binding Path=Ville.ID}" SelectedValuePath="ID" />
    Avec ce code, ça marche, sauf que la propriété Ville de mon objet Membre n'est jamais renseignée, vu que le DataContext de la combo est la DataView qui contient la liste des villes ayant le même CodePostal... J'ai besoin de ce DataContext uniquement pour le ItemsSource (défini en code-behind), mais pas pour le SelectedItem. J'espère avoir été clair.
    Comment résoudre ce problème ?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Enlève le SelectedItem="{Binding Path=Nom}"
    Ta combobox contient des Villes pas des String, donc le SelectedItem ne peut pas être une chaine... Le SelectedValue devrait suffire à gérer ça proprement

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    J'ai enlevé le SelectedItem, mais toujours pareil. En outre, j'ai absolument besoin de cette propriété.
    Un exemple :
    Je tape dans la textbox CodePostal : "06500" => Immédiatement, la combobox Ville contient les 5 villes correspondantes, avec la première sélectionnée. Je choisis la ville du membre en question, qui est la 3e de la liste. Je sélectionne un autre membre, puis je reviens sur le membre modifié => dans la combobox Ville, la ville sélectionnée est la première !
    En fait, ce qui se passe, c'est que ma combobox Ville est bindée à la DataView créée à partir du Code Postal rentré mais elle devrait aussi être bindée à la propriété MonMembre.Ville. Le multibinding serait-il la solution au problème ? Si oui, comment le mettre en place ?

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Bon, je viens de me rendre compte que j'ai un message d'erreur du moteur de binding qui me signale que :
    BindingExpression Path Error : 'ID' Property not found on 'object' 'DataRowView' [...]
    Effectivement, la propriété ID n'existe pas, elle s'appelle VilleID, oops ! Mais bon, ça ne résout rien.
    Et puis, dans mes explications de tout à l'heure, je me suis légèrement trompé aussi. En fait, le DataContext de la cboVille, comme de tous les autres contrôles, est un objet Membre (sélectionné dans une listbox). C'est le ItemsSource de la combo Ville qui est défini sur la DataView.
    J'ai également modifié le SelectedItem de la cboVille comme ceci : SelectedItem="{Binding Path=Ville}".
    Ce qui me tue, c'est que j'ai dans la même window, une combobox Statut qui fonctionne parfaitement et est calquée sur le même modèle : à savoir la propriété Statut de mon objet Membre est un objet Statut. La seule différence avec la ville, c'est que l'ItemsSource est une ObservableCollection et non une DataView, et tout fonctionne très bien.
    Pourquoi dans le cas de ma combo Ville, ça foire ?

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Un dessin valant mieux qu'un long discours, voici un diagramme peut-être plus explicatif...
    Voir le diagramme

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Ton SelectedValuePath, il faut mettre "VilleID" et non "ID"

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Oui, effectivement, c'est une étourderie !
    Mais le problème reste intact ! Lorsque je sélectionne un autre membre et que je reviens sur le membre modifié, la textbox CodePostal contient bien celui que j'ai rentré ; la combobox contient bien les villes correspondantes mais aucun item n'est sélectionné (celui que j'avais sélectionné est donc perdu...)

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut Ooops !
    Bon, je viens de me rendre compte que je me suis trompé dans le diagramme.
    Voici le diagramme correct.
    Donc j'ai modifié le xaml pour la combo ville :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=Ville}" SelectedValue="{Binding Path=Ville.ID}" SelectedValuePath="VilleID" />
    Par contre, dans la DataView, la colonne correspondante est bien VilleID. C'est pour ça que j'ai renseigné le SelectedValuePath ainsi. Car dans les tutoriels trouvés sur le net sur le binding d'une combobox, il est dit que :
    • le SelectedValue définit la propriété de l'objet lié (donc ici mon objet membre) qui sera utilisé pour récupérer la valeur
    • le SelectedValuePath correspond à la propriété de la Liste liée (chez moi, c'est une DataView) qui doit correspondre (c'est donc bien VilleID).

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Je viens de m'apercevoir que j'avais une erreur de binding sur le SelectedItem qui, d'après l'erreur mentionée, se réfère à l'ItemSource et non pas à l'objet lié. J'ai donc modifié en conséquence le xaml de la combobox ville :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=VilleID}" SelectedValue="{Binding Path=Ville.ID}" SelectedValuePath="ID" />
    Par contre, j'ai fait un test : je renseigne le code postal et je choisis une ville. J'affiche ensuite les propriétés de l'objet membre correspondant => Résultat : membre.Ville.ID contient bien l'ID, membre.Ville.CodePostal contient bien le code postal , par contre membre.Ville.Nom est vide !

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Je crois avoir trouvé d'où vient l'erreur :
    dans le cas du Statut, le SelectedItem est un objet Statut de l'ObservableCollection (qui est l'ItemsSource) ; dans le cas de la Ville, le SelectedItem se trouve être une DataRowView de la DataView (qui est l'ItemsSource) => C'est pour ça qu'en mettant le SelectedItem=Ville, il m'indiquait une erreur de binding (en le mettant sur VilleID, je n'ai plus d'erreur mais ça ne change rien au résultat). Comment définir ce SelectedItem pour avoir le résultat escompté ?

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Je viens de faire un autre test :
    sur l'évènement SelectionChanged de la combobox Ville, j'affiche une Msgbox m'indiquant : le SelectedItem, SelectedValue et SelectedValuePath.
    => Résultats :
    SelectedItem = System.Data.DataRowView
    SelectedValue = l'ID de la ville
    SelectedValuePath = VilleID

    C'est donc bien le SelectedItem qui foire, mais comment le définir correctement ?

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Je me demande si je ne vais tout simplement pas créer une ObservableCollection d'objets Ville à partir de la DataView et binder cette collection à ma combobox Ville. Je désespère de trouver la solution à mon problème. Là, je commence à saturer et à ne plus trop comprendre...

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par jacquesprogram Voir le message
    => Résultats :
    SelectedItem = System.Data.DataRowView
    SelectedValue = l'ID de la ville
    SelectedValuePath = VilleID

    C'est donc bien le SelectedItem qui foire, mais comment le définir correctement ?
    Ben non, le SelectedItem est correct... si la source de données est une DataView, c'est normal que le SelectedItem soit un DataRowView (celui qui correspond à la ville sélectionnée)

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    Oui, mais alors comment se fait-il que le comportement ne soit pas celui attendu ?

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Je crois que je commence à comprendre...
    - la propriété Ville de la classe Membre est de type Ville
    - tu veux sélectionner la ville à partir d'une ComboBox liée à une DataView
    - les élements de la ComboBox sont donc des DataRowView représentant des villes, et non des instances de la classe Ville

    Donc je ne vois pas comment tu pourrais lier le SelectedItem de cette ComboBox à la propriété Ville du Membre, vu que ce n'est pas le même type...

    C'est d'ailleurs la seule différence avec le cas du Statut qui fonctionne bien : pour le statut, l'ItemsSource est une ObservableCollection d'objets Statut, alors que pour la ville c'est une DataView. Il faudrait que la source soit une collection d'objets Ville, et non une DataView... Si c'est le filtrage qui te pose problème, c'est assez simple à réaliser en WPF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    string cp = textBoxCodePostal.Text;
    ICollectionView view = CollectionViewSource.GetDefaultView(listVilles);
    view.Filter = (obj) =>
        {
            Ville v = (Ville)obj;
            return (v.CodePostal == cp)
        };
    D'autre part, il ne faut pas binder la TextBox du code postal au code postal de la ville ! En faisant ça, tu permets à l'utilisateur de modifier le code postal de la ville du membre, ce qui devrait être interdit : l'utilisateur n'est pas supposé changer le code postal d'une ville... Ce champ ne sert finalement que comme critère de recherche pour sélectionner la ville.

  16. #16
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut Un pas vers la lumière...
    Bon, je suis toujours en train de tester mon binding. Voici ce que j'ai fait :
    Lorsque j'affiche ma window :
    • Je sélectionne un membre
    • Je rentre le code postal et je choisis dans la combo Ville la ville
    • Je ferme la window => la msgbox de test m'indique bien pour membre.Ville.Nom la ville que j'ai choisie
    • Je rouvre la window
    • Je sélectionne le joueur précédemment édité => le SelectedItem de la combo ville est bien celui que j'avais choisi. OUF !

    MAIS :
    Si je sélectionne un autre membre et que je reviens sur le membre précédemment modifié, là, la combo ville n'a plus aucun item sélectionné !!!
    Pourquoi ce comportement ?

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    OK tomlev, merci de tes éclaircissements. J'ai oublié de préciser dans mon précédent message les changements effectués : j'ai abandonné la DataView et j'ai créé une ObservableCollection d'objets Ville ; ensuite une CollectionView filtrée grâce au Code Postal rentré (ça, ça ne me pose pas de problème) qui est bindée à la combo Ville. Et j'ai le comportement cité dans mon précédent post.
    Je remets le code Xaml de la combo Ville :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=Ville}" SelectedValue="{Binding Path=Ville.ID}" SelectedValuePath="ID" />
    En outre, oui, je veux que l'utilisateur puisse taper un code postal, non pas pour changer le code postal d'une ville, mais lorsqu'il tape un nouveau CP, la combo se met à jour automatiquement pour lister les villes correspondant à ce CP (cette partie-là fonctionne très bien aussi).

  18. #18
    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
    Citation Envoyé par jacquesprogram Voir le message
    En outre, oui, je veux que l'utilisateur puisse taper un code postal, non pas pour changer le code postal d'une ville, mais lorsqu'il tape un nouveau CP, la combo se met à jour automatiquement pour lister les villes correspondant à ce CP (cette partie-là fonctionne très bien aussi).
    Dans ce cas là, il faut que tu fasses comme te l'indique tomlev: tu filtre ta collectionview en fonction de ce que l'utilisateur saisi dans la zone de texte.

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Août 2006
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 582
    Points : 265
    Points
    265
    Par défaut
    C'est bien ce que je fais : la CollectionView bindée à la combobox est le résultat du filtre basé sur le code postal entré par l'utilisateur. Mon problème ne se situe pas là mais sur le SelectedItem de la combo qui n'est pas défini sur la ville choisie, si je sélectionne un autre membre et que je reviens ensuite sur le membre où j'ai défini la ville (comme expliqué dans mon msg "Un pas vers la lumière")...

  20. #20
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par jacquesprogram Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=Ville}" SelectedValue="{Binding Path=Ville.ID}" SelectedValuePath="ID" />
    A mon avis c'est ce code qui pose problème... il y a un conflit entre le SelectedValue et le SelectedItem
    Il faudrait mettre seulement SelectedItem :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <ComboBox DisplayMemberPath="Nom" SelectedItem="{Binding Path=Ville}" />
    Parce qu'au fond tu t'en fous de l'ID, c'est la ville elle-même que tu sélectionnes... Si ton Membre avait une propriété VilleID, tu utiliserais un binding sur SelectedValue = VilleID, mais là le membre a directement un objet Ville

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 4 1234 DernièreDernière

Discussions similaires

  1. Problème définition nouveau projet GTK
    Par Clopinet85 dans le forum GTK+ avec C & C++
    Réponses: 16
    Dernier message: 06/05/2013, 17h26
  2. [WPF]Problème d'update de binding
    Par guitoux1 dans le forum Windows Presentation Foundation
    Réponses: 11
    Dernier message: 12/06/2007, 17h42
  3. problème de récursivité avec .bind
    Par polo42 dans le forum Tkinter
    Réponses: 2
    Dernier message: 30/04/2007, 18h52
  4. Problème définition constructeur
    Par bugland dans le forum Langage
    Réponses: 11
    Dernier message: 12/02/2007, 14h34
  5. problème définition alias
    Par julien.63 dans le forum Apache
    Réponses: 2
    Dernier message: 26/10/2006, 17h41

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