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

Framework .NET Discussion :

[WPF] Binding et type custom


Sujet :

Framework .NET

  1. #1
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 17
    Points : 10
    Points
    10
    Par défaut [WPF] Binding et type custom
    Je travaille avec VS2008 Beta 2 et le framework 3.5.
    Je fais du binding qui fonctionne bien, mais j'ai un cas que je n'arrive pas à résoudre.
    Je vous donne d'abord le cas qui fonctionne bien, et ensuite mon problème.

    CAS QUI FONCTIONNE :
    J'ai une liste de cette classe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class CFctBase : INotifyPropertyChanged
    {
         public object Value
         {
               get;
               set;
         }
     
     ....
    }

    Je binde un élément de cette liste à un controle de la manière suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
         void test(CFctBase o_fct)
         {
         Binding o_binding = o_binding = new Binding("Value");
         my_label.SetBinding(Label.ContentProperty, o_binding);
         my_label.DataContext = o_fct;
         }
    Jusque là Value est instantié comme un type string, tout va bien.
    Lorsque je mets à jour l'attribut Value de mon instance o_fct, my_label se met bien à jour tout va bien.

    CAS QUI NE FONCTIONNE PAS:
    Maintenant, je voudrais faire la même chose mais Value est un type custom.
    Il est de type CommProtocol.IMultiArray.
    Ce type possède un attribut MultiArray qui renvoie une collection.

    Bien sur, maintenant je binde Value sur un listview, puisque c'est une collection et là tout va bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       Binding o_binding = new Binding();
       lvMain.SetBinding(ListView.ItemsSourceProperty, o_binding);
       lvMain.DataContext = (o_fct.Value as CommProtocol.IMultiArray).MultiArray;
    Cela fonctionne mais dans ce cas, mon listview n'est pas rafraichi si Value change.
    Ce que je voudrais c'est faire quelque chose de ce style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         Binding o_binding = new Binding("MultiArray");
         lvMain.SetBinding(ListView.ItemsSourceProperty, o_binding);
         lvMain.DataContext = o_fct.Value as CommProtocol.IMultiArray;
    Mais bien sur ça ne fonctionne pas, mais je ne sais pas trop comment contourner le problème.
    Passer par un ODP ?

    Merci d'avance pour vos idées.

  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
    Points : 19 434
    Points
    19 434
    Par défaut
    J'ai.... rien compris

    Tu pourrais nous réexpliquer tout cela mais plus.... clairement ?



  3. #3
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Mince, moi qui ai essayé de faire simple
    C'est un peu dur à expliquer en fait...

    j'ai un controle qui est un label : my_label
    j'ai une instance de ma classe CFctBase

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class CFctBase : INotifyPropertyChanged
    {
         public object Value
         {
               get;
               set;
         }
    
     ....
    }
    Par le code dans une méthode "test", je binde le contenu de mon label à l'attribut Value de mon instance.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void test(CFctBase o_fct)
         {
         Binding o_binding = o_binding = new Binding("Value");
         my_label.SetBinding(Label.ContentProperty, o_binding);
         my_label.DataContext = o_fct;
         }
    A présent dans ma window, mon label affiche bel et bien la valeur "Value", et si je modifie "Value", mon label se met bien à jour, car c'est une string qui lui est affectée.


    Bon, j'espère que vous avez suivi jusque là


    Maintenant, dans une autre window, je veux binder l'itemsource d'une listview à une zutre instance de CFctBase dont Value est affecté par un type "maison".
    Ce type maison est "dans mon exemple" appelé IMultiArray et possède un attribut MultiArray, qui renvoie une liste de strings.

    Si je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
       Binding o_binding = new Binding();
       lvMain.SetBinding(ListView.ItemsSourceProperty, o_binding);
       lvMain.DataContext = (o_fct.Value as IMultiArray).MultiArray;
    ca marche, mais ma listview n'est pas rafraichie si le contenu de la source change (c'est à dire si je modifie Value).

    Donc j'aurais voulu écrire qq chose de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         Binding o_binding = new Binding("(Value as IMultiArray).MultiArray");
         lvMain.SetBinding(ListView.ItemsSourceProperty, o_binding);
         lvMain.DataContext = o_fct;
    ....pour que le refresh fonctionne

    Euh, vous m'avez suivie ?

  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
    Points : 19 434
    Points
    19 434
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class CFctBase : INotifyPropertyChanged
    {
         public object Value
         {
               get;
               set;
         }
     
     ....
    }
    Donc ton set, tu as bien pensé à implémenter l'interface ? Et à appeller l'event de notification de mise à jour de l'IHM ?

  5. #5
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 17
    Points : 10
    Points
    10
    Par défaut
    Oui oui, comme dit, dans mon premier example le refresh fonctionne, car je fais bien le binding sur l'instance de CFctBase avec le path sur Value.
    Comme je binde sur un type qui implémente INotifyBiduleTruc, le refresh fonctionne.

    Si je prends toujours le premier example où j'affecte Value avec un type string, et que je binde sur CFctBase.Value avec un path vide, le refresh ne se fait pas non plus (puisque je binde sur un type string, c'est logique).

    Donc dans mon deuxième exemple, je voudrais trouver comment me binder à mon instance de CFctBase et mettre le Path en conséquence, mais je ne vois pas comment affecter le Path à "(Value as IMultiArray).MultiArray".
    Je pense qu'il faut peut-être passer par un objectDataProvider ou faire carrément autrement ?

  6. #6
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 17
    Points : 10
    Points
    10
    Par défaut YOUPIIIII
    Ca marche !!


    En fait j'ai fait un converter<object, "le type de mon MultiArray">
    Je précise que le type de mon MultiArray est ObservableCollection<List<string>>.
    Ce type me permet de coller à un controle de type GridView.
    J'ai bindé mon listView sur une instance de ma classe CFctBase et mis le path sur Value (comme dans mon premier exemple quoi).

    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
     
        [ValueConversion(typeof(object), typeof(ObservableCollection<List<string>>))]
        public class CObjectToObservableListStringConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                ObservableCollection<List<string>> o_ret;
     
                if (typeof(CommProtocol.IMultiArray).IsAssignableFrom(value.GetType()))
                {
                    o_ret = (value as CommProtocol.IMultiArray).MultiArray;
                }
                else
                {
                    o_ret = new ObservableCollection<List<string>>();
                }
     
                return o_ret;
            }
     
            public object ConvertBack(object value, Type TargetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return null;
            }
        }
    Je fais le binding de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Binding o_binding = new Binding("Value");
    o_binding.Converter = new CObjectToObservableListStringConverter();
    lview.SetBinding(ListView.ItemsSourceProperty, o_binding);

    Et le refresh de mon listview se fait comme par magie !
    C'est beauuuu, je suis contente

    Pourtant j'utilisais déjà des converters, j'aurais du y penser avant.
    C'est drole une fois qu'on trouve la solution, ça parait évident

    Je précise encore un peu plus : chacune des colonnes de mon GridView est bindée sur un élément de ma liste de strings de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for (int i = 0; i < col_count; i++)
    {
          GridViewColumn o_col = new GridViewColumn();                     
          o_col.DisplayMemberBinding = new Binding("[" + i + "]");
          lview.Columns.Add(o_col);
    }
    Pour conclure, ce code binde dynamiquement un gridview à un objet générique (de type object), mais qui est instancié en un type ObservableCollection<List<string>>
    - ObservableCollection contient les lignes
    - List contient les colonnes
    - string est le contenu d'une cellule

    J'imagine que si ma question était incompréhensible, la réponse l'est encore plus, mais bon je poste quand même, ça peut donner des idées à d'autres...

  7. #7
    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
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par sehshe Voir le message
    J'imagine que si ma question était incompréhensible, la réponse l'est encore plus, mais bon je poste quand même, ça peut donner des idées à d'autres...
    Je confirme


    Mais merci tout de même, ca servira sans doute à d'autre

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

Discussions similaires

  1. [WPF] Binding & Type
    Par NeoKript dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 25/06/2012, 16h14
  2. wpf binding avec un dataset sans listbox
    Par ZashOne dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 25/12/2007, 19h09
  3. [WPF][Binding] Comment binder un fichier XML sur un treeview?
    Par bakonu dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 26/11/2007, 17h09
  4. [WPF] Binding sur app.config
    Par despeludo dans le forum Windows Presentation Foundation
    Réponses: 2
    Dernier message: 24/10/2007, 22h56
  5. Réponses: 2
    Dernier message: 12/12/2006, 22h14

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