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 :

Comment récupérer la propriété IsChecked d'une CheckBox définie en DataTemplate ?


Sujet :

Windows Presentation Foundation

  1. #1
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut Comment récupérer la propriété IsChecked d'une CheckBox définie en DataTemplate ?
    Bonjour tout le monde,
    je pense que le titre est un peu obscur, donc voici quelques explications
    J'ai définit une ListView bindée sur une liste de string et je les affiche avec une CheckBox, voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <ListView Name="lvValeur1" Grid.Row="0" AlternationCount="2"
              ItemsSource="{Binding Path=ValeurList}"
              ItemContainerStyle="{StaticResource StyleZebre}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    Je souhaite ensuite récupérer les valeurs cochées en code, après quelques tâtonnements, j'ai trouvé le code qui me permet de remonter à la CheckBox affichée, mais il ne fonctionne pas car il m'indique que toutes les valeurs sont décochées alors que dans la fenêtre j'en coche à la main, voici le code que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    foreach (string item in lvValeur1.Items)
    {
        ListViewItem lvi = (ListViewItem)lvValeur1.ItemContainerGenerator.ContainerFromItem(item);
        DataTemplate dt = lvi.ContentTemplate;
        CheckBox cb = (CheckBox)dt.LoadContent();
        MessageBox.Show((cb.IsChecked == true).ToString());
    }
    Quelle est mon erreur ?

    Existe-t-il une solution plus simple ou aboutir au résultat ?

    Merci d'avance pour votre aide.

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    il faut introspecter les element avec le visual tree
    regarde sur mon blog y'a un exemple presque identique a tes besoins
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  3. #3
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Salut ikeas, merci pour ton aide, mais tu es sûr qu'il n'existe pas une solution plus simple ?

    Car au final, elle impose de créer une fonction récursive et générique pour aboutir au résultat.

    Par curiosité, j'ai essayé de le faire à la main, à partir du ListViewItem, on retrouve le Border, puis un Presenter et enfin la CheckBox.

    Je me pose des questions sur les problèmes de performances que l'on risque d'avoir si le ListView possède des milliers de valeurs. En effet, si le ListView possède 10 000 valeurs et qu'on souhaite retrouve la valeur sélectionnée, il suffit de faire une énumération sur la propriété SelectedItems, mais si on souhaite retrouve la valeur cochée, on doit passer l'ensemble des items et pour chacun introspecter le VisualTree, j'ai peur que les temps de réponse soient totalement différents.

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 220
    Points
    220
    Par défaut
    Au lieu de binder sur une collection de string tu bindes sur une collection d'objet du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public class Item
    	{
    		public string Label
    		{
    			get;
    			set;
    		}
    		public bool IsChecked
    		{
    			get;
    			set;
    		}
    	}
    et pour le DataTemplate tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <DataTemplate>
                <CheckBox Content="{Binding Label}"  IsChecked={Binding IsChecked}/>
            </DataTemplate>

  5. #5
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Salut matdur, j'étais justement en train de réfléchir à ce genre de solution car j'ai d'autres problèmes avec l'autre solution.

    En effet, il n'est pas possible d'accéder à l'ensemble des CheckBox via le TreeviewHelper car la méthode ItemContainerGenerator.ContainerFromItem(item) renvoie nul dès que l'item n'est pas affiché à l'écran.
    Je m'en suis rendu compte en voulant faire des tests de performance sur 10 000 items.

    Par contre matdur, j'ai un souci dans la mise en place de cette solution. En effet, ma ListView est actuellement bindée sur une propriété ValeurList de l'objet métier sélectionné dans un Treeview se trouvant dans la même fenêtre.
    Ainsi, lorsque l'utilisateur sélectionne un autre élément, la liste se met automatiquement à jour via le binding.

    Si je binde le ListView à une liste d'objets Item déclarée en private de la fenêtre je vais perdre ce lien.

  6. #6
    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 WebPac Voir le message
    Car au final, elle impose de créer une fonction récursive et générique pour aboutir au résultat.
    Et alors ? Ce n'est pas une petite méthode récursive qui va poser problème....

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 220
    Points
    220
    Par défaut
    Tu fais comment actuellement ? Tu mets bien a jour la liste "ValeurList" en fonction de la sélection de l'utilisateur. Et bien tu fais pareil sauf que "ValeurList" n'est plus une collection de "string" mais un collection de "Item"

  8. #8
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Et alors ? Ce n'est pas une petite méthode récursive qui va poser problème....
    C'est juste qu'on fait compliqué pour qqch qui ne paraît pas l'être de prime abord.
    Mais de toute façon, cette solution ne fonctionne pas puisqu'il n'est possible d'accéder qu'aux CheckBox visibles.

    Citation Envoyé par matdur Voir le message
    Tu fais comment actuellement ? Tu mets bien a jour la liste "ValeurList" en fonction de la sélection de l'utilisateur. Et bien tu fais pareil sauf que "ValeurList" n'est plus une collection de "string" mais un collection de "Item"
    Il ne m'est pas possible de modifier le code de l'objet métier qui possède la propriété ValeurList, cet objet possède une liste de string et je ne peux pas la changer en liste d'item.

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 220
    Points
    220
    Par défaut
    Au lieu de binder sur "ValeurList" tu bindes sur une collection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	public ObservableCollection<Item> Items
    		{
    			get;
    			set;
    		}
    que tu renseignes de la manière suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Items = ValeurList.Select( valeur => new ItemCollection{ Label = valeur});

  10. #10
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Citation Envoyé par matdur Voir le message
    Au lieu de binder sur "ValeurList" tu bindes sur une collection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	public ObservableCollection<Item> Items
    		{
    			get;
    			set;
    		}
    que tu renseignes de la manière suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Items = ValeurList.Select( valeur => new ItemCollection{ Label = valeur});
    Salut, en fait je n'ai pas été assez explicite sur la ValeurList, c'est une propriété d'un autre objet métier, appelons-le Champ.

    La ListView se trouve dans un TabControl qui est défini ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <TabControl Name="tcFiltre" Grid.Column="2"
                DataContext="{Binding ElementName=tvChamp, Path=SelectedItem}">
    Et tvChamp est un Treeview possédant une arborescence de Champ.

    Ainsi, lorsque l'utilisateur sélectionne un autre champ dans le Treeview, le binding du TabControl change de champ et le ListView affiche la ValeurList du nouveau champ.

    En fait, je me demande s'il ne serait pas possible de faire la conversion du string en Item possédant un Label et un booléen dans un Converter par exemple, mais je n'arrive pas à le gérer encore, mais je continue à chercher.

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 220
    Points
    220
    Par défaut
    Peut-être que tu devrais faire du MVVM et binder non pas sur le model mais sur le view-model. Tu peux créer une classe ChampViewModel qui possède une collection de ItemViewModel

  12. #12
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Salut,

    pour l'instant vu la taille du projet, il n'est pas prévu de mettre le MVVM en place, mais de toute façon cette décision ne m'appartient pas.

    J'ai définit un converter de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return ((System.Collections.ObjectModel.ObservableCollection<string>)value).Select(valeur => new Tuple { Label = valeur });
            }
    Avec l'objet Tuple qui correspond à ton objet Item :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public class Tuple
        {
            public string Label { get; set; }
            public bool IsCoched { get; set; }
        }
    Ensuite, j'utilise ce Converter dans le binding sur L'ItemsSource du ListView.

    Le ListView affiche donc bien des Tuple et le changement de champ est bien bindé aussi avec la liste affichée dans le ListView.

    Seul problème que je n'ai pas encore résolu :
    Lorsqu'on met à jour la liste de valeurs dans ValeurList, cela ne met pas à jour la ListView puisque la liste des tuples n'est pas bindée avec la ValeurList.

    Je me demande s'il ne serait pas possible de justemement les binder ensemble, mais je ne m'y connais pas très bien encore là-dessus, mais je vais regarder ce qu'il est possible de faire.

  13. #13
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Salut tout le monde,

    j'ai presque réussi à faire le truc, mon dernier problème est que je n'ai pas réussi à relier la ValeurList qui est une ObservableCollection de string avec l'observableCollection de Tuple, donc l'ajout de valeurs dans la première ne se met pas à jour dans la ListBox.

    Par contre, je suis en train de lire un tutoriel qui explique le MVVM pour voir ce qu'il est possible d'en tirer pour résoudre ce problème et s'il ne peut pas apporter une solution plus simple et plus jolie car je trouve que j'ai fait du code un peu "bidouille" pour l'instant.

  14. #14
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    ben oui si tu met un mvvm qui possede le checked tu n'a plus qu'a binder
    c'est en substance ce que t'avais dit thomas je crois
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  15. #15
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Citation Envoyé par ikeas Voir le message
    ben oui si tu met un mvvm qui possede le checked tu n'a plus qu'a binder
    c'est en substance ce que t'avais dit thomas je crois
    Non tu confonds, Thomas a juste dit qu'une méthode récursive n'était pas un problème, c'est matdur qui avait soulevé cette idée.

    Je suis quand même embêté car la solution pour mon problème m'oblige à modifier en profondeur le projet et mettre en place le MVVM qui est plus recommandé sur des projets ayant entre autre des designer, nous ne sommes que 1 et demi sur mon projet, je trouve ça un peu lourd de devoir le mettre en place pour ce besoin.

    J'aurais aimé trouver une autre solution rapidement implémentable qui ne nécessite pas trop de développement mais on dirait que ce n'est pas possible.

  16. #16
    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
    MVVM n'implique pas un projet avec Designer. Ca te permet aussi la testabilité, la scalabilité, etc... pour ton projet, designer présent ou pas

  17. #17
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    et puis le mvvm c'est relativement simple aussi a mettre en oeuvre
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  18. #18
    Membre confirmé Avatar de WebPac
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 947
    Points : 512
    Points
    512
    Par défaut
    Citation Envoyé par ikeas Voir le message
    et puis le mvvm c'est relativement simple aussi a mettre en oeuvre
    Oui et non.
    Je suis en train de lire un tuto se trouvant sur ce site qui l'explique avec un exemple simple.

    En effet, quand on prend l'exemple, tout parait simple et évident, mais quand on n'en a pas l'habitude et qu'on devait le faire sans exemple, on ne penserait pas à un certain nombre de points, comme le fait de devoir redévelopper une classe qui implémente ICommand, d'ailleurs je ne sais pas pourquoi il faut le faire.
    Mais c'est sur que quand on voit l'implémentation de ICommand dans l'exemple, c'est simple, mais on ne peut pas le trouver seul, enfin pas en début.

    Sinon, ce qui est fort appréciable, c'est qu'on adapte tout dans le ModelView pour que le binding soit direct sans avoir à utiliser 36 Converter ni de les MultiBinding ou autre BindingGroup. Ca c'est sûr c'est fort appréciable.

  19. #19
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    attend deja tu as le mvvm qui adapte ton objet metier au besoin visuel notament celui dédié au binding
    apres tu peux aussi faire les commandes mais c'est pas non plus une obligation
    ca depand aussi du besoin
    les commandes ne sont introduite que lorsque que tu veux faire en sorte que ta classe view model possede aussi le comportement
    en general le metier possede son comportement propre
    par exemple les commande sont intéressante
    pour )
    - ajouter un element au model
    - supprimer
    - etc ...
    en gros dans le view model tu as le comportement d'interface
    a ne pas confondre bien sur
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  20. #20
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 220
    Points
    220
    Par défaut
    Je te conseille les liens suivants pour commencer

    http://www.lab49.com/files/videos/Ja...ger%20MVVM.wmv

    http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    sinon tu trouves aussi des liens intéressants sur des articles et sur différents frameworks mvvm dans la page Wikipédia

    http://en.wikipedia.org/wiki/Model_View_ViewModel

Discussions similaires

  1. Comment récupérer les élements sélectionnés d'une ListBox ?
    Par Bleuarff dans le forum Composants VCL
    Réponses: 11
    Dernier message: 23/02/2013, 06h36
  2. Réponses: 1
    Dernier message: 18/05/2006, 11h37
  3. Réponses: 12
    Dernier message: 02/03/2006, 14h13
  4. Réponses: 3
    Dernier message: 22/01/2005, 22h06
  5. Réponses: 5
    Dernier message: 21/12/2004, 18h12

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