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 :

une checkbox SelectAll en MVVM ?


Sujet :

C#

  1. #1
    Membre à l'essai
    Homme Profil pro
    concepteur développeur Informatique
    Inscrit en
    Avril 2018
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : concepteur développeur Informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2018
    Messages : 19
    Points : 15
    Points
    15
    Par défaut une checkbox SelectAll en MVVM ?
    Bonjour,

    j'ai quelques soucis pour créer, comme dit le texte, une checkbox qui me permet de "selectionner tout" dans un modele MVVM.
    Après avoir cherché, j'ai un résultat qui ne fonctionne pas, et je me demandais si vous pouviez m'aider à ce sujet;

    Mon objet :

    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 partial class Matrix : ObservableObject
    {
        public string IDMatrice { get; set; }
        private bool _IsSelectedDay;
        public bool IsSelectedDay
        {
            get
            {
                return _IsSelectedDay;
            }
            set
            {
                if (value != _IsSelectedDay)
                {
                    _IsSelectedDay = value;
                    RaisePropertyChanged(nameof(IsSelectedDay));
                }
            }
        }
    }
    Si j'ai bien compris, je dois rajouter une propriété pour la selection, comme ceci.

    Ensuite, dans le ViewModel :

    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
    48
    49
    50
    51
        private bool _AllSelectedDays;
        public bool AllSelectedDays
        {
            get
            {
                return _AllSelectedDays;
            }
            set
            {
                _AllSelectedDays = value;
                foreach (var idMatrice in this.Matrice)
                {
                    idMatrice.IsSelectedDay = value;
                }
                RaisePropertyChanged(nameof(AllSelectedDays));
            }
        }
     
            private ObservableCollection<Matrix> _Matrice;
        public ObservableCollection<Matrix> Matrice
        {
            get
            {
                return _Matrice;
            }
            set
            {
                if (value != _Matrice)
                {
                    _Matrice = value;
                    RaisePropertyChanged(nameof(Matrice));
                }
            }
        }
     
        private Matrix _SelectedMatrice;
        public Matrix SelectedMatrice
        {
            get
            {
                return _SelectedMatrice;
            }
            set
            {
                if (value != _SelectedMatrice)
                {
                    _SelectedMatrice = value;
                    RaisePropertyChanged(nameof(SelectedMatrice));
                }
            }
        }
    Et enfin, dans le WPF :

    Code XAML : 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
    <Window x:Class="GET_MS.Views.WPFChangerEtablissement"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GET_MS.ViewModels"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
        xmlns:cuilv="clr-namespace:ClassUILibrary.Views;assembly=ClassUILibrary"
        mc:Ignorable="d"
        DataContext="{Binding ChangerEtablissement, Source={StaticResource Locator}}" 
     
    <DataGrid Name="DgMatrice" Grid.Column="2" Margin="2" AlternatingRowBackground="LightBlue" AlternationCount="2" CanUserAddRows="False"  
                              ItemsSource="{Binding Matrice}">
                        <DataGrid.Columns>
                            <DataGridTemplateColumn>
                                <DataGridTemplateColumn.Header>
                                    <CheckBox IsChecked="{Binding Path=DataContext.AllSelectedDays,RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                                </DataGridTemplateColumn.Header>
                                <DataGridTemplateColumn.CellTemplate >
                                    <DataTemplate >
                                                <CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding IsSelectedDay}"/>
                                            </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>

    Ce que j'obtiens, ce sont des combobox qui n'ont aucun effet quand je les coches :

    Nom : 6rFMG.png
Affichages : 122
Taille : 6,0 Ko

    (je ne rentre même pas dans le "selectedAllDays")

    et une nouvelle colonne dans ma DataGrid du coup :

    Nom : 7ufOq.png
Affichages : 120
Taille : 2,3 Ko

    Qui a un effet étrange. Si je coche la case 2 ici, ça me cochera la case 1 tout à gauche. Et ainsi de suite : 3 => 2, 4 => 3...

    Edit : c'est réparé, si je selectionne une des cases, je passe bien par "IsSelectedDay", de ce côté là ça roule. Par contre, je ne passe jamais dans "AllSelectedDay", et là je bloque...

    Une idée pour me sortir de là ?

  2. #2
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    C’est du "Deductive reasoning" ou raisonnement par déduction ,qui se fourvoie s'il est trop pratiqué "intensivement" devant un problème simple...
    Çà nécessite de prendre l'air et allez voir ...un aquarium de poissons exotiques (les aiguilleurs du ciel de l’aéroport de New York font parait-il ça,quand il y a trop d'avions)...
    ton code revu:

    1/class data exemple:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
     
    namespace WpfApplication1
    {
        public class ObservableObject:INotifyPropertyChanged 
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public void Raise(string s)
            {
               PropertyChangedEventHandler h=PropertyChanged;
                if (h !=null) 
                    h(this,new PropertyChangedEventArgs(s));
     
            }
        }
    }
     
     
     
     
     
     
        public partial class Employe : ObservableObject
        {
            private string _employeID;
            public string EmployeID 
            {
                get
                {
                    return _employeID;
                }
                set
                {
                    if (value != _employeID)
                    {
                        _employeID = value;
                        Raise("EmployeID");
                    }
                }
            }
            private bool _isSelected;
            public bool IsSelected
            {
                get
                {
                    return _isSelected;
                }
                set
                {
                    if (value != _isSelected)
                    {
                        _isSelected = value;
                        Raise("IsSelected");
                    }
                }
            }
            private bool _isSelectedDay;
            public bool IsSelectedDay
            {
                get
                {
                    return _isSelectedDay;
                }
                set
                {
                    if (value != _isSelectedDay)
                    {
                        _isSelectedDay = value;
                        Raise("IsSelectedDay");
                    }
                }
            }
        }
        public class  ListEmployes:List<Employe>
        {
            public ListEmployes()
            {
                for (int i = 11; i < 21; i++)
                {
                    Employe emp = new Employe() {EmployeID=i.ToString(), IsSelectedDay=false  };
                    this.Add(emp);
                }
            }
     
     
        }
     
    public class VMAllEmployes:ObservableObject
        {
            private ListEmployes myList = new ListEmployes();
            public VMAllEmployes()
            {
                _employes =new ObservableCollection<Employe>(myList);
     
            }
            private bool _AllSelectedDays;
            public bool AllSelectedDays
            {
                get
                {
                    return _AllSelectedDays;
                }
                set
                {
                    if (value != _AllSelectedDays)
                    {
                        _AllSelectedDays = value; ;
                        if (_AllSelectedDays)
                        {
                            for (int i = 0; i < Employes.Count; i++)
                            {
                                Employes[i].IsSelectedDay = true;
                            }
                            Raise("SelEmployes");
                            Raise("AllSelectedDays");
                        }
                        else
                        {
                            for (int i = 0; i < Employes.Count; i++)
                            {
                                Employes[i].IsSelectedDay = false;
                            }
                            Raise("SelEmployes");
                            Raise("AllSelectedDays");
                        }
     
     
     
     
                    }
                    Raise("AllSelectedDays");
                }
            } 
            private ObservableCollection<Employe> _employes;
            public ObservableCollection<Employe> Employes
            {
                get
                {
                    return _employes;
                }
                set
                {
                    if (value != _employes)
                    {
                        _employes = value;
                        Raise("Employes");
                    }
                }
            }
        }
    xaml du form User:

    Code XAML : 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
    <Window x:Class="WpfApplication1.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication1" 
            Title="Window1" Height="350" Width="525"
            >
        <Window.DataContext>
            <local:VMAllEmployes/>
        </Window.DataContext>
        <Grid>
     
            <DataGrid 
                Name="dgEmploye" 
                Grid.Column="0"
                Margin="2" 
                CanUserAddRows="False"  
                SelectionMode="Single" 
                ItemsSource="{Binding Employes}">
                <DataGrid.Columns>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.Header>
                            <CheckBox 
                                Background="Beige" 
                                FontSize="18"
                                Foreground="Red" 
                                Content="Select All" IsChecked="{Binding Path=DataContext.AllSelectedDays,RelativeSource={RelativeSource AncestorType=DataGrid}}"/>                    </DataGridTemplateColumn.Header>
                        <DataGridTemplateColumn.CellTemplate >
                            <DataTemplate >
                                <CheckBox 
                                    Background="Beige"
                                    HorizontalAlignment="Center" VerticalAlignment="Center" 
                                    IsChecked="{Binding IsSelectedDay}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridCheckBoxColumn 
                        Binding="{Binding IsSelectedDay}"/>
                    <DataGridTextColumn Binding="{Binding EmployeID}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    Pour info le DataGrif Wpf expose une prop SelectedItems (scelerate et inutile ) mais en lecture seule et qu'il est impossible de s'y "binder" ...

    si tu veux récupérer tes éléments ,il faudra rajouter à ton VM une prop de type ObservableCollection<Employe> AllDayEmployes...
    bon code...

  3. #3
    Membre à l'essai
    Homme Profil pro
    concepteur développeur Informatique
    Inscrit en
    Avril 2018
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : concepteur développeur Informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Avril 2018
    Messages : 19
    Points : 15
    Points
    15
    Par défaut
    En effet, ce n'était pas très compliqué, merci du deblocage.

    J'ai une question d'ordre pratique, suite à votre commentaire. Datagrid ou ListView dans cette situation? Y'a-t-il un choix préconisé par rapport à un autre ?

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    Bonjour

    J'ai une question d'ordre pratique, suite à votre commentaire. Datagrid ou ListView dans cette situation? Y'a-t-il un choix préconisé par rapport à un autre ?
    - Datagrid est plus pratique car il dispose de fonctions de modification
    - ListView ne le permet pas...
    Au surplus la prop SelectedItems du ListView est egalement "scélérate et inutile" c.à.d eb lecture seule ...

  5. #5
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    rebonjour

    Comme deja dit le "Deductive reasoning" ou raisonnement par déduction ,est mauvais
    s'il est pratiquement "intensivement" et à tort ...

    On peut y perdre son latin ou son cerveau ('lose your mind")...

    Voici une approche pour résoudre ton épineux problème par l'approche du modèle dirigé par les données ou MVVM ...

    Comme le probleme pose consiste à partir:
    - d'une prop (AllSelectedDays) du "parent" (VMAllEmployes) à setter la prop (IsSelected) de chaque "child" (Employe)

    => il faut que chaque "child" ait une référencé sur le "parent" .
    Comme le "parent" implemente INotifyPropertyChanged le probleme est resolu

    1/ class Data
    code behind .cs deja donné mais revu:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
     
    namespace WpfApplication3
    {
     
     
     
         public class ObservableObject:INotifyPropertyChanged 
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public void Raise(string s)
            {
               PropertyChangedEventHandler h=PropertyChanged;
                if (h !=null) 
                    h(this,new PropertyChangedEventArgs(s));
     
            }
        }
     
     
    public partial class Employe : ObservableObject
        {
            public Employe()
            { 
     
            }
            public Employe(VMAllEmployes   pvm):this()
            {
                VM = pvm;
            }
            private string _employeID;
            public string EmployeID
            {
                get
                {
                    return _employeID;
                }
                set
                {
                    if (value != _employeID)
                    {
                        _employeID = value;
                        Raise("EmployeID");
                    }
                }
            }
            private bool _isSelectedDay;
            public bool IsSelectedDay
            {
                get
                {
                    return _isSelectedDay;
                }
                set
                {
                    if (value != _isSelectedDay)
                    {
                        _isSelectedDay = value;
                        Raise("IsSelectedDay");
                    }
                }
            }
            private VMAllEmployes _vm;
     
            public VMAllEmployes VM
            {
                get { return _vm; }
                set
                {
     
                    if (value != _vm)
                    {
                        _vm = value;
                        VM.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(VM_PropertyChanged);
                        Raise("VM");
                    }
     
     
                }
            }
     
            void VM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                VMAllEmployes maindmodel=sender as VMAllEmployes ;
                if (e.PropertyName == "AllSelectedDays")
                    this.IsSelectedDay = maindmodel.AllSelectedDays;
            }
     
        }
        public class ListEmployes : List<Employe>
        {
            public ListEmployes(VMAllEmployes  vm  )
            {
                for (int i = 11; i < 21; i++)
                {
                    Employe emp = new Employe(vm) { EmployeID = i.ToString(), IsSelectedDay = false };
                    this.Add(emp);
                }
            }
     
     
        }
     
     
    public class VMAllEmployes:ObservableObject
        {
     
            private ListEmployes myList =null ;
            public VMAllEmployes()
            {
                myList = new ListEmployes(this);
                _employes =
                    new ObservableCollection<Employe>(myList);
            }
            private bool _allSelectedDays;
            public bool AllSelectedDays
            {
                get
                {
                    return _allSelectedDays; 
                }
                set
                {
                    if (value != _allSelectedDays)
                    {
                        _allSelectedDays = value;
     
                        Raise("AllSelectedDays");
                    }
                }
            }
            private ObservableCollection<Employe> _employes;
            public ObservableCollection<Employe> Employes
            {
                get
                {
                    return _employes;
                }
                set
                {
                    if (value != _employes)
                    {
                        _employes = value;
                        Raise("Employes");
                    }
                }
            }
        }
     
     
     
     
    }
    code xaml du Form déjà donné mais revu:
    Code XAML : 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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:local="clr-namespace:WpfApplication3" 
            Title="MainWindow" Height="350" Width="525">
        <Window.DataContext>
            <local:VMAllEmployes/>
        </Window.DataContext>
        <Window.Resources>
            <DataTemplate x:Key="HeaderCheckbox"  >
                <CheckBox 
                    x:Name="chkHeader" 
                    Content="Select All" FontSize="18" Foreground="Red" 
                    IsChecked="{Binding RelativeSource={RelativeSource  
                    Mode=FindAncestor, AncestorType=DataGrid}, 
                    Path=DataContext.AllSelectedDays, Mode=TwoWay}" >
                </CheckBox>
            </DataTemplate >
     
            <DataTemplate x:Key="ItemCheckbox" >
                <CheckBox 
                    x:Name="chkItem"
                    IsChecked="{Binding RelativeSource={RelativeSource  
                    Mode=FindAncestor, AncestorType=DataGrid}, 
                    Path=DataContext.AllSelectedDays, Mode=TwoWay}" >
                </CheckBox>
            </DataTemplate >
            <DataTemplate x:Key="ItemCheckboxDay" >
                <CheckBox 
                    x:Name="chkItem"
                    Content="Sel Day"
                    IsChecked="{Binding  Path=IsSelectedDay, Mode=TwoWay}" >
                </CheckBox>
            </DataTemplate >
        </Window.Resources>
     
     
        <Grid>
            <DataGrid 
                Name="dgEmploye" 
                Margin="2" 
                AutoGenerateColumns="False"  
                CanUserAddRows="False"  
                SelectionMode="Single" 
                ItemsSource="{Binding Employes}"
                >
                <DataGrid.Columns>
                    <DataGridTemplateColumn
                            HeaderTemplate="{StaticResource HeaderCheckbox}"
                            CellTemplate="{StaticResource ItemCheckbox}">
                    </DataGridTemplateColumn>
                    <DataGridTextColumn 
                        Header="Employe ID"
                        Binding="{Binding EmployeID}">
                    </DataGridTextColumn>
                    <DataGridTextColumn 
                        Header="VM Info"
                        Binding="{Binding VM.AllSelectedDays}">
                    </DataGridTextColumn><DataGridTemplateColumn
                        Header="Select Day"
                        CellTemplate="{StaticResource ItemCheckboxDay}">
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>

    bon code...

Discussions similaires

  1. Readonly sur une checkbox
    Par Oluha dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 14/02/2005, 11h09
  2. [FLASH MX] Police d'une Checkbox
    Par n_tony dans le forum Flash
    Réponses: 5
    Dernier message: 08/12/2004, 12h04
  3. Etat coché ou décoché d'une checkbox
    Par El Saigneur dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 05/10/2004, 16h56
  4. [XML][XSL]afficher une checkbox cochée
    Par kirk80 dans le forum XMLRAD
    Réponses: 2
    Dernier message: 16/09/2004, 17h49
  5. [struts] mémorisation d'une checkbox avec cookie
    Par rocco dans le forum Struts 1
    Réponses: 3
    Dernier message: 22/04/2004, 12h39

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