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 :

Observable Collection - Data Binding


Sujet :

Windows Presentation Foundation

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut Observable Collection - Data Binding
    Bonjour, j'utilise wpf depuis un certain temps mais il est vrai que je ne suis pas encore tout à fait alaise avec le data binding ^^

    Objectif : Mon application servira à bindé une fenêtre sur une touche du clavier afin de naviguer plus facilement de fenêtre en fenêtre.
    MyProject : https://windowbinding.codeplex.com/

    Pour mon projet je dispose d'une fenêtre principale contenant une ListBox d'UserControl.
    Ces UserControl dispose de 2 combo-box une qui listera les fenêtre en cours d’exécution et l'autre a bindé les touches sur celle-ci.

    Pour ce faire j'ai crée 2 classe (Dossier Behaviors) héritant de l'interface INotifyPropertyChanged destiné à être utiliser dans mes observable collections.
    Dans mon MainWindow je crée une propriété qui renvoi un tuple qui contient mes 2 observable collections destiné à être passé en paramètre a mon UC.

    Problème :

    1) Test

    En créant 1 seul UC est en lui passant en paramètre (Dependency property) mon tuple je suis obliger de "rafraichir" le source de la combobox (de mon UC) a chaque modification de ma collection

    MainWindow -> Xaml :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <local:HandleBindingUC Name="UC1" CbxItemsSource="{Binding BindingCBXSource, Mode=TwoWay}">
    MainWindow -> Cs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UC1.CbxItemsSource = BindingCBXSource;
    2) Test

    En créant une listbox est en modifiant le template afin d'y ajouter mon UC en tant qu'item j'ai du faire une boucle pour réaffecté ma collection comme précédemment sauf que cette fois si cela ne fonctionne plus (c'est la méthode que j'utilise actuellement sur mon projet lien codeplex)

    Finalité : je voudrais avoir juste à ajouté des éléments dans ma collection et que les combo-box ce mettent à jour toute seul.

    Merci de votre aide, Quentin.

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Personne ?

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Pour faire ce que tu veux, actuellement seule la classe "ObservableCollection" (ainsi que ses dérivées) fait cela grâce à ses événements "CollectionChanged" et "PropertyChanged"...

    http://msdn.microsoft.com/fr-fr/libr...v=vs.110).aspx

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Justement j'utilise déjà des observable collections :

    MainWindows.xaml.cs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public ObservableCollection<Behaviors.KeyCollection> enableKeys = new ObservableCollection<Behaviors.KeyCollection>();
    public ObservableCollection<Behaviors.BindingCollections> bindingsCBX = new ObservableCollection<Behaviors.BindingCollections>();
    Voici ma classe KeyCollection :
    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
     
    using KKey = System.Windows.Input.Key;
     
    public class KeyCollection : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            private KKey key;
     
            public KKey Key
            {
                get { return key; }
                set 
                {
                    if (value != this.key)
                    {
                        this.key = value;
                        NotifyPropertyChanged();
                    }
                }
            }
     
            private bool enable;
     
            public bool Enabled
            {
                get { return enable; }
                set 
                {
                    if (value != this.enable)
                    {
                        enable = value;
                        NotifyPropertyChanged();
                    }
                }
            }
     
     
     
            private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

  5. #5
    Invité
    Invité(e)
    Par défaut
    OK, je n'avais pas vu que tu utilisais déjà les bonnes classes.
    Ton objet de liste est bien fait comme il faut...

    Mais je vois que tu associes la liste à une propriété personnalisée de ton UserControl qui s'appelle "CbxItemsSource".
    Alors si j'ai bien compris le UC contient 2 comboboxes? Mais je n'ai pas très bien compris à quel moment tu retransmet le contenu de "CbxItemsSource" au membre "ItemsSource" de la combobox? Car si tu ne fais pas cela, ça ne peut pas fonctionner...

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Le lien de mon projet : https://windowbinding.codeplex.com/

    Sinon l'item source des combobox de l'UC sont bindé sur le dependency property comme suit :

    UC.xaml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ComboBox Height="25" Width="50" DockPanel.Dock="Right" ItemsSource="{Binding CbxItemsSource, Converter={StaticResource bindingsCollectionConverter}, ConverterParameter=Key, Mode=TwoWay}"></ComboBox>
    UC.xaml.cs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public Tuple<ObservableCollection<Behaviors.BindingCollections>, ObservableCollection<Behaviors.KeyCollection>> CbxItemsSource
            {
                get { return (Tuple<ObservableCollection<Behaviors.BindingCollections>, ObservableCollection<Behaviors.KeyCollection>>)GetValue(ItemSourceCBX); }
                set { SetValue(ItemSourceCBX, value); }
            }
     
            // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty ItemSourceCBX =
                DependencyProperty.Register("CbxItemsSource", typeof(Tuple<ObservableCollection<Behaviors.BindingCollections>, ObservableCollection<Behaviors.KeyCollection>>), typeof(HandleBindingUC));

  7. #7
    Invité
    Invité(e)
    Par défaut
    Je vois que tu utilises un "Converter" pour ton objet.
    Je pense qu'en fait le problème est là : que renvoie la méthode "Convert" de ta classe qui implémente "IValueConverter"?
    En effet, si à chaque conversion demandée elle renvoie un nouvel objet "ObservableCollection", c'est la raison pour laquelle tes objets ne se mettent pas à jour tout seul.

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Il renvois un IEnumerable après quelque test le problème ce situerais au niveau du converter :

    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
     
    [ValueConversion(typeof(Tuple<ObservableCollection<Behaviors.BindingCollections>, ObservableCollection<Behaviors.KeyCollection>>), typeof(IEnumerable<string>))]
        public class BindingsCollectionConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                IEnumerable<string> enumerableList = null;
                var bindings = value as Tuple<ObservableCollection<Behaviors.BindingCollections>, ObservableCollection<Behaviors.KeyCollection>>;
     
                if (bindings == null)
                    return enumerableList;
     
                if ((parameter as string) == "Handle")
                {              
                    enumerableList = from bind in bindings.Item1 where bind.Enabled == true select bind.HandleName;
                }
                else if ((parameter as string) == "Key")
                {
                    enumerableList = from bind in bindings.Item2 where bind.Enabled == true select bind.Key.ToString();
                }
                else
                    throw new NotSupportedException("Parameter is not supported !");
     
                return enumerableList;
            }
    }

  9. #9
    Invité
    Invité(e)
    Par défaut
    Oui, c'est ça. Le "Convert" est appelé à chaque fois qu'il accède à ta propriété databindée convertie. Du coup il renvoie à chaque fois une nouvelle instance, donc il ne peut pas suivre les modifications puisqu'il y a une instance différente à chaque fois. Si tu renvoyais directement "Item1" ou "Item2", tu n'aurais pas ce problème, car utilisation de la même référence donc du même ObservableCollection.

    Après, je vois que tu veux utiliser un filtre supplémentaire pour enlever ceux qui ne sont pas "Enabled"...

    Il faut voir si, une fois converti, il n'est pas possible d'appliquer un filtre avec une "vue"...

    Au niveau de ton UserControl, il te suffit normalement de faire un "CollectionViewSource.GetDefaultView" sur ton "ItemsSource" de la combobox (à ce moment là il est converti normalement) pour obtenir une vue de type "ICollectionView". Une fois que tu as obtenu la vue, il faut alors définir son membre "Filter" avec le prédicat du filtre voulu.

    N'hésites pas à consulter la doc en ligne MSDN sur les classes et interfaces dont j'ai parlé.

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Au niveau de ton UserControl, il te suffit normalement de faire un "CollectionViewSource.GetDefaultView" sur ton "ItemsSource" de la combobox (à ce moment là il est converti normalement) pour obtenir une vue de type "ICollectionView". Une fois que tu as obtenu la vue, il faut alors définir son membre "Filter" avec le prédicat du filtre voulu.
    Oui, je suis d'accord mais du coups mon ObservableCollection de type KeyCollection expose 2 propriétés :

    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
     
    using KKey = System.Windows.Input.Key;
     
            private KKey key;
     
            public KKey Key
            {
                get { return key; }
                set 
                {
                    if (value != this.key)
                    {
                        this.key = value;
                        NotifyPropertyChanged();
                    }
                }
            }
     
            private bool enable;
     
            public bool Enabled
            {
                get { return enable; }
                set 
                {
                    if (value != this.enable)
                    {
                        enable = value;
                        NotifyPropertyChanged();
                    }
                }
            }
    Comment faire pour afficher toute mes "Key" dans ma combobox sachant que Key est un énumérable de System.Windows.Input.Key sans passer par un converter ?

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par quentin869 Voir le message
    Comment faire pour afficher toute mes "Key" dans ma combobox sachant que Key est un énumérable de System.Windows.Input.Key sans passer par un converter ?
    Un "enum" pour être plus précis, à ne pas confondre avec les interfaces "IEnumerable".

    En fait ça désigne une combinaison de touches. Normalement, même avec le "ToString" par défaut.

    Pour ta combobox, il devrait y avoir une propriété du genre "DataDisplayMember" ou qqch comme ça pour lui dire quel membre il faut afficher. Si un Converter doit être appliqué, il y a aussi la possibilité de faire des datatemplates.

  12. #12
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 37
    Par défaut
    Merci de m'avoir rectifier ^^, donc j'ai utiliser un datatemplate comme tu me la proposer j'ai définis l'itemsource de ma combobox sur ma collection et dans le datatemplate j'ai appliquer un converter :

    Xaml :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <ComboBox Height="25" Width="50" DockPanel.Dock="Right" ItemsSource="{Binding CbxItemsSource2}">
            <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Key, Converter={StaticResource keyConverter}}"/>
                    </DataTemplate>
            </ComboBox.ItemTemplate>
    </ComboBox>
    Converter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            return value.ToString();
        }
        else
            return value;
    }
    Merci beaucoup pour ton aide

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

Discussions similaires

  1. [Débutant] Problématique pour le binding des éléments d'une Observable Collection
    Par mrflamby dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 07/09/2015, 13h12
  2. Réponses: 7
    Dernier message: 17/04/2014, 09h31
  3. Data Binding et DependencyProperty
    Par gege02 dans le forum C#
    Réponses: 1
    Dernier message: 22/06/2007, 10h36
  4. [VB.NET]data binding et bindingcontext dur a trouver
    Par thierry007 dans le forum Windows Forms
    Réponses: 7
    Dernier message: 02/12/2006, 15h45
  5. [XML] XML Data Binding vers php
    Par noa dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 01/03/2006, 16h31

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