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

C# Discussion :

[WPF] Comment lire l'état d'une CheckBox qui est dans une GridVIew dans une ListView?


Sujet :

C#

  1. #1
    Membre éclairé Avatar de shkyo
    Homme Profil pro
    Développeur Robotique - Administrateur systèmes
    Inscrit en
    Juin 2003
    Messages
    841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Robotique - Administrateur systèmes

    Informations forums :
    Inscription : Juin 2003
    Messages : 841
    Par défaut [WPF] Comment lire l'état d'une CheckBox qui est dans une GridVIew dans une ListView?
    Bonjour à tous,

    Je bosse sur une interface en WPF qui utilise une ListView dans laquelle il y a un GridView qui est groupable, et qui doit avoir des CheckBox... Visuellement j'arrive à le décrire en XAML et ça donne ça:
    Nom : Interface_WPF.JPG
Affichages : 1090
Taille : 20,1 Ko

    Mon problème est le suivant: comment j'accède à l'état de mes CheckBox?...

    Voici mon code XAML:
    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
            <ListView x:Name="lvUsers" HorizontalAlignment="Left" Height="250" Margin="341,30,0,0" VerticalAlignment="Top" Width="550">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Name" Width="250">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox Name="CB_Nom" Margin="30,0,5,0" Content="{Binding Path=Name}" Checked="CB_Nom_Checked"
                                              IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <!--<GridViewColumn Header="Name" Width="200" DisplayMemberBinding="{Binding Name}" />-->
                        <GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
                    </GridView>
                </ListView.View>
     
                <ListView.GroupStyle>
                    <GroupStyle>
     
                        <GroupStyle.ContainerStyle>
                            <Style TargetType="{x:Type GroupItem}">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Expander IsExpanded="True">
                                                <Expander.Header>
                                                    <StackPanel Orientation="Horizontal">
                                                        <CheckBox x:Name="CB_Titre" Margin="3,7,5,0"></CheckBox>
                                                        <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="18" VerticalAlignment="Bottom" />
                                                        <TextBlock Text="{Binding ItemCount}" FontSize="18" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="5,0,0,0" VerticalAlignment="Bottom" />
                                                        <TextBlock Text=" élément(s)" FontSize="16" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
                                                    </StackPanel>
                                                </Expander.Header>
                                                <ItemsPresenter />
                                            </Expander>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </GroupStyle.ContainerStyle>
     
                    </GroupStyle>
                </ListView.GroupStyle>
            </ListView>
    Je suis preneur de toute idée ou suggestion... Merci d'avance!

  2. #2
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Tu veux y accéder côté Xaml ou côté C# / ViewModel ? Dans le second cas tu y accèdes déjà via le binding sur la propriété IsChecked. Mais je pense que tu devrais rajouter un TargetType sur ton DataTemplate. Par contre c'est quoi ce Checked="CB_Nom_Checked" ? Je n'ai pas l'impression que ça fasse partie des propriétés d'une CheckBox.

  3. #3
    Membre éclairé Avatar de shkyo
    Homme Profil pro
    Développeur Robotique - Administrateur systèmes
    Inscrit en
    Juin 2003
    Messages
    841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Robotique - Administrateur systèmes

    Informations forums :
    Inscription : Juin 2003
    Messages : 841
    Par défaut
    Citation Envoyé par Noxen Voir le message
    Tu veux y accéder côté Xaml ou côté C# / ViewModel ? Dans le second cas tu y accèdes déjà via le binding sur la propriété IsChecked. Mais je pense que tu devrais rajouter un TargetType sur ton DataTemplate. Par contre c'est quoi ce Checked="CB_Nom_Checked" ? Je n'ai pas l'impression que ça fasse partie des propriétés d'une CheckBox.
    Je veux y accéder dans mon code C#, d'abord pour pouvoir gérer le cas du titre coché qui doit donc cocher ses CheckBox enfants, et bien sûr pour savoir quelles CheckBox sont cochées au final pour pouvoir faire les traitements associés... Justement, pour l'instant je n'arrive à accéder à la propriété IsChecked ...

    Comme je ne suis pas à l'aise en WPF, je picore des infos sur le net et le Checked="CB_Nom_Checked" vient d'un précédent essai que j'ai réalisé à partir d'un TreeView dans lequel j'avais mis des CheckBox que je contrôlais sans problème, mais je gérais chaque CheckBox individuellement, ce qui est plus simple... Et dans ce TreeView j'avais donc Checked= et Unchecked= sur chaque élément.

    Je suis passé sur un GridView dans une ListView car mes données seront issues d'un fichier Excel, donc au final j'aurais 5 ou 6 colonnes de data à gérer.

  4. #4
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Il faut tout d'abord que ton view model implémente INotifyPropertyChanged, directement ou par une classe l'implémentant déjà (ViewModelBase dans MVVMLight) ; de cette façon l'objet informera ses observateurs de ses changements et pourront se mettre à jour :

    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
     
    namespace Checking.ViewModel
    {
        public class ItemViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
     
            private string _label;
            public string Label
            {
                get { return _label; }
                set
                {
                    if (value == _label) return;
                    _label = value;
                    OnPropertyChanged();
                }
            }
     
            private bool _isSelected;
            public bool IsSelected
            {
                get { return _isSelected; }
                set
                {
                    if (value == _isSelected) return;
                    _isSelected = value;
                    OnPropertyChanged();
                }
            }
        }
    }
    Puis dans le view model de ta fenêtre (ou peut-être l'ItemViewModel lui-même, si c'est une règle intrinsèque) tu t'abonnes à cet événement PropertyChanged et tu modifie la valeur IsSelected des enfants immédiats (qui notifieront leurs propres enfants).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var ivm = new ItemViewModel { Label = "Blop" };
    ivm.PropertyChanged += (s, e) =>
    {
        var item = (ItemViewModel)s;
        switch (e.PropertyName)
        {
            case "IsSelected":
            foreach (var child in GetChildren(item)) child.IsSelected = item.IsSelected;
            break;
        }
    };

  5. #5
    Membre éclairé Avatar de shkyo
    Homme Profil pro
    Développeur Robotique - Administrateur systèmes
    Inscrit en
    Juin 2003
    Messages
    841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Robotique - Administrateur systèmes

    Informations forums :
    Inscription : Juin 2003
    Messages : 841
    Par défaut
    Merci Noxen pour ta réponse, mais je bataille depuis hier sans succès pour l'instant... Faut dire que jusqu'à maintenant, je n'ai pas utilisé (ou alors sans le savoir...) le système MVVM...

    J'ai créé un fichier ViewModelBase.cs, que j'ai bien sûr ajouté en using, mais il ne veut rien savoir sur le GetChildren(item) (que j'ai ajouté dans mon MainWindows.xaml.cs ) et je ne trouve pas la librairie qui contient cette instruction...

    Tu dis qu'on peut implémenter INotifyPropertyChanged directement, ce serait peut-être plus simple dans mon cas, mais dans ce cas-là comment faire??

    Merci d'avance!

  6. #6
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Citation Envoyé par shkyo Voir le message
    je n'ai pas utilisé (ou alors sans le savoir...) le système MVVM...
    Le pattern MVVM (Model-View-ViewModel) est un modèle d'architecture qui s'intègre naturellement avec WPF. La library MVVMLight de Laurent Bugnion propose des fonctionnalités pour faciliter un développement en MVVM ; on peut la récupérer via NuGet. Elle adjoint au projet les classes ViewModelLocator et MainViewModel et crée dans le app.xaml une ressource de type ViewModelLocator nommée Locator. Dans la définition de la fenêtre (balise Window de MainWindow.xaml) il faut assigner au DataContext la propriété Main du locator pour récupérer un MainViewModel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DataContext="{Binding Main, Source={StaticResource Locator}}"
    Citation Envoyé par shkyo Voir le message
    J'ai créé un fichier ViewModelBase.cs
    Je faisais allusion à l'une des classes fournies par MVVMLight.

    Citation Envoyé par shkyo Voir le message
    il ne veut rien savoir sur le GetChildren(item) (que j'ai ajouté dans mon MainWindows.xaml.cs )
    La fonction n'existe pas, c'est juste un exemple pour dire qu'on veut accéder aux enfants d'un nœud.

    Citation Envoyé par shkyo Voir le message
    Tu dis qu'on peut implémenter INotifyPropertyChanged directement, ce serait peut-être plus simple dans mon cas, mais dans ce cas-là comment faire??
    Tu as l'exemple au début de l'implémentation de ItemViewModel. Mais si tu rajoute une interface sur une classe Visual Studio devrait te proposer une implémentation par défaut de l'interface.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public class ItemViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    Dans les propriétés dont tu veux notifier le changement tu ajoute un appel à la méthode OnPropertyChanged().

Discussions similaires

  1. Réponses: 3
    Dernier message: 17/02/2017, 13h16
  2. Comment contrôler l'état de 4 checkbox
    Par pierrot10 dans le forum jQuery
    Réponses: 2
    Dernier message: 08/12/2013, 21h45
  3. [POI] lire l'état d'un checkbox
    Par nlsbo dans le forum Documents
    Réponses: 2
    Dernier message: 30/04/2009, 08h50
  4. Réponses: 9
    Dernier message: 05/12/2007, 11h34
  5. voir comment est alimentée une vue qui est dans dba_objects
    Par meufeu dans le forum Administration
    Réponses: 15
    Dernier message: 06/10/2004, 17h27

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