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 :

Binding XAML : typer un SelectedItem


Sujet :

Windows Presentation Foundation

  1. #1
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut Binding XAML : typer un SelectedItem
    Bonjour,

    Est-t-il possible de forcer le type d'un SelectedItem de façon à récupérer également les attributs en plus des propriétés de l'objet retourné par SelectedItem ?

    J'ai créé un CustomControl MaTextBox qui hérite de TextBox. Lorsque la propriété Text est bindée, un label contenant le libellé de la propriété est automatiquement ajouté devant la TextBox. Ce libellé est défini dans un Attribut personnalisé de ma propriété. Jusque ici tout le monde suit ? Besoin d'un petit exemple ? Prenons donc le cas simplissime de la "personne" :
    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
     
    public class Personne
    {
    <div style="margin-left:40px">
    string _Nom;
    string _Prenom;
     
    [MonAttribut(Libelle="Nom de la personne :", Nullable=False)]
    public string Nom
    {
    <div style="margin-left:40px">
    Get { return _Nom; }
    Set { _Nom = value; }</div>}
     
    [MonAttribut(Libelle="Prénom de la personne :")]
    public string Prenom
    {
    <div style="margin-left:40px">
    Get { return _Prenom; }
    Set { _Prenom = value; }</div>}</div>}
    Lorsque je défini mon Binding en XAML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // PersonneDS est ODP
    <MaTextBox Text="{Binding Path=Nom, Source={StaticResource PersonneDS}}"/>
    J'obtient une jolie TextBox précédée d'un lable "Nom de la Personne :" (ainsi qu'un astérix caractérisant le fait que cette donnée ne soit pas nullable contrairement à Prenom mais là n'est pas le sujet... )

    Si maintenant je remplie une ListView avec une ObservableCollection<Personne> et que je définie une zone de saisie, permettant la modification des propriétés, bindée sur le SelectedItem, je n'arrive plus à récupérer mes Attributs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // PersonneCollectionDS est ODP
    <ListView x:Name="listePersonne" ItemsSource="{Binding PersonneCollectionDS}" ... />
    <MaTextBox Text="{Binding Path=SelectedItem.Nom, ElementName=listePersonne}"/>
    Peut-on signifier dans le Binding qu'il s'agit d'un type "Personne" et non "Object" (ce que renvoie SelectedItem) ? Faire une sorte de CAST ?
    Ou faut-il que je revois mon approche ?

    Merci à ceux qui aurons pris le temps de me lire.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Hum... en passant par un Converter ?

  3. #3
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Hum... en passant par un Converter ?
    Bonjour Thomas,

    Merci de t'être penché sur le sujet mais j'avais pensé au Converter et je ne vois pas comment cela pourrait me permettre de récupérer les Attributs. D'autant que l'utilisation d'un converter s'effectue sur la propriété elle-même et non sur l'objet.

    Je suis en train de creuser une autre piste. Je bind le DataContext d'un Panel contenant mes CustomControls en utilisant cette fois un converter sur le selectedItem tout entier. Mais j'ai une exception à l'execution... Je creuse, je creuse...

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    En passant par un Converter, tu récupère l'objet que tu caste en ton type et là, tu récupères les attributs par réflexion.

    Pas forcément le mieux mais cela semble correspondre à ce que j'ai compris de ton besoin.....

  5. #5
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    En passant par un Converter, tu récupère l'objet que tu caste en ton type et là, tu récupères les attributs par réflexion.

    Pas forcément le mieux mais cela semble correspondre à ce que j'ai compris de ton besoin.....
    J'ai essayé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <ListView x:Name="listePersonne" ItemsSource="{Binding PersonneCollectionDS}" ... />
    <StackPanel DataContext="{Binding Path=SelectedItem, ElementName=listePersonne, Converter={StaticResource ObjectToPersonneConverter}}">
    <div style="margin-left:40px">
    <MaTextBox Text="{Binding Path=Nom}"/>
    <MaTextBox Text="{Binding Path=Prenom}"/></div></StackPanel>
    Mais ça ne fonctionne pas. DataContext renvoie également un type object. Vois tu une autre methode que celle-ci pour utiliser le converter ?

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Fais voir le code de ton ObjectToPersonneConverter

    Il doit prendre en paramètre un objet (le SelectedItem) et renvoyer un objet de type Personne

  7. #7
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Fais voir le code de ton ObjectToPersonneConverter

    Il doit prendre en paramètre un objet (le SelectedItem) et renvoyer un objet de type Personne
    C'est ce qu'il fait :
    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
     
    [ValueConversion(typeof(object), typeof(Personne))]
    public class ObjectToPersonneConverter : IValueConverter
    {
    <div style="margin-left:40px">     
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    <div style="margin-left:40px">
    if (value != null)
    <div style="margin-left:40px">return value as Personne;</div>return null;</div>}
     
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    <div style="margin-left:40px">
    if (value != null)
    <div style="margin-left:40px">return value as object;</div>return null;        </div>}</div>}
    Mais je ne pense pas que le souci se trouve dans l'utilisation d'un converter.
    Le Binding s'effectue chaque fois sur un type object (SelectedItem et DataContext renvoie toujours un type object).

    La solution serait d'ajouter le converter au Binding qui se fait sur la propriété elle-même... Impossible, il ne s'agit plus d'un type personne mais en l'occurence d'un type string.

    J'ai donc pensé à implémenter mon control en récupérant le type de l'objet source lorsqu'il s'agit d'un element d'une collection (blablabla...). Un peu lourd mais ça devrait fonctionner.

    D'autre part, l'ensemble des propriétés de mes controls (comme le libellé, le "Nullable" etc.) sont des DependencyProperties, je peux donc leur affecter une valeur dans le XAML.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <MaTextBox caption="Nom de la personne :" ... />
    Ce problème n'en est donc pas réellement un sinon qu'il soit nécessaire d'ajouter du code pour automatiser l'apparence de mes controls.

    Merci pour ton aide Thomas


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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Si tu renvois bien un objet de type Personne sur le DataContext, il est surprenant que le DataBinding ne fonctionne pas par la suite

    Tu es sur que le:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    value as Personne;
    ne vaut pas null à tout hasard ?

  9. #9
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Si tu renvois bien un objet de type Personne sur le DataContext, il est surprenant que le DataBinding ne fonctionne pas par la suite

    Tu es sur que le:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    value as Personne;
    ne vaut pas null à tout hasard ?
    Le binding fonctionne, ma propriété Text est bien celle que j'attend. C'est toujours les attributs qui me manquent. Mon DataContext de type object possède bien les propriétés auxquelles je lie mes controls mais pas les attributs

    J'ai aussi tenté de contourné ce problème en déclarant un ODP du type de base de ma collection (dans l'exemple il s'agit du type Personne) mais je me vois contraint de gérer l'event ItemSelectionChanged pour aller mettre à jour l'ObjectInstance de mon ODP à chaque changement de selection. Dans ce cas ça fonctionne mais ce n'est pas très élégant.

    Si je pouvais lier mon ODP.ObjectInstance au SelectedItem... Malheureusement il n'est pas possible d'appliquer un Binding sur une instance qui ne soit pas un FrameWorkElement. J'ai bon là ?

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par Goj17 Voir le message
    Le binding fonctionne, ma propriété Text est bien celle que j'attend. C'est toujours les attributs qui me manquent.
    Ah, c'est les attribut qu'il te faut... Désolé, j'avais pas compris

    Bon, si tu arrives à récupérer un objet de type Personne, je pense que tu vas pouvoir t'en sortir avec un autre converter, dans le binding, à ce niveau:


    <MaTextBox Text="{Binding Path=Nom}"/>

    Là, tu accèdes à ton DataContext (Personn), dessus, tu fais de la réflexion pour accéder aux attributs et ensuite, tu renvois la chaine de caractères.

  11. #11
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Là, tu accèdes à ton DataContext (Personn), dessus, tu fais de la réflexion pour accéder aux attributs et ensuite, tu renvois la chaine de caractères.
    Je ne comprend pas, si je passe par un converter au niveau de la propriété "Nom" je ne peux connaitre le type du DataContext dans le converter.

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Tu fais pas un converter sur la propriété Nom mais sur .:

    <MaTextBox Text="{Binding Path=., Converter=XXX}"/>

    Dans ton converter, tu accèdes à ton objet Person et plus spécifiquement à la propriété Nom. Ensuite, un peu de réflexion et c'est tout.

  13. #13
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Tu fais pas un converter sur la propriété Nom mais sur .:

    <MaTextBox Text="{Binding Path=., Converter=XXX}"/>

    Dans ton converter, tu accèdes à ton objet Person et plus spécifiquement à la propriété Nom. Ensuite, un peu de réflexion et c'est tout.
    Ok, j'ai compris. Je ne connaissais pas le "." dans le Path.
    Ceci m'oblige cependant à écrire un converter pour chaque propriété bindée ou à passer la propriété que je cible en paramètre. Je vais continuer à creuser.

    Merci

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par Goj17 Voir le message
    Ok, j'ai compris. Je ne connaissais pas le "." dans le Path.
    Ceci m'oblige cependant à écrire un converter pour chaque propriété bindée ou à passer la propriété que je cible en paramètre. Je vais continuer à creuser.

    Merci
    Non, tu peux passer un parametre (Parameter) au convertisseur donc à toi de l'utiliser pour savoir quelle propriété à aller chercher

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Je t'ai mis en PJ de ce post un exemple de ce à quoi je pense.

    - Une ListBox bindée à une collection de personne.
    - 2 TextBlocks bindées à la propriété SelectedItem de la ListBox.
    - Sur la classe Person, j'ai des attributs perso
    - Lors du binding, je passe par un converter et son paramètre pour accéder à l'attribut perso (et sa valeur) et l'afficher dans les TextBlock


    A+
    Fichiers attachés Fichiers attachés

  16. #16
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Merci thomas, vraiment très sympa pour le code en PJ.
    Par contre, je suis désolé mais il me reste un problème, dans mon cas il ne suffit pas de concatener une chaine de caractères, mais de me servir des attributs pour renseigner les DP de mon control. Il s'agit d'un Custom control constitué d'un label (le caption), d'un TextBox (la valeur) etc. Tout ceci défini dans un style dans mon Generic.xaml.

    Je vais tenter de me servir de la reflection pour retourner la propriété dont j'ai besoin comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return Person.FirstName

  17. #17
    Membre averti
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Par défaut
    Je ne trouve vraiment pas de solution à mon problème.

    Peut-être qu'il est possible d'apporter une solution par un converter mais cela me semble plus lourd que la gestion de l'événement "SelectedItemChanged" dans ma liste pour mettre à jour l'instance de mon deuxième ODP déstiné à la saisie.

    J'ai également d'autres propriétés utilisées par mon FrameWork de mapping (objet chargé ou créé, modifié etc.) dont la gestion deviendrait difficile.

    Il reste également la possibilité d'implementer ce cas particulier dans mon control.

    En ce qui me concerne, je vais plutôt passer à la decouverte de LINQ et autres techno dont j'ai entendu parler aux techDays08.

    En tout cas merci pour ton aide

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

Discussions similaires

  1. Double Binding xaml
    Par Lionhart dans le forum C#
    Réponses: 2
    Dernier message: 18/09/2014, 11h02
  2. [MVVM] Binding xaml sur une List/ObserveableCollection du Model plutôt que sur une propriété du Model
    Par uluquiorra dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 21/11/2012, 18h43
  3. PB de Binding (XAML)
    Par l.mnu dans le forum C#
    Réponses: 3
    Dernier message: 27/07/2012, 14h30
  4. Dependency property et Binding XAML
    Par PPierre59 dans le forum Silverlight
    Réponses: 3
    Dernier message: 15/06/2010, 23h46
  5. problème binding xaml
    Par cyberchand dans le forum C#
    Réponses: 6
    Dernier message: 14/02/2007, 16h10

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