Search code examples
c#mvvmcombobox

Binding some checkbox into combobox to a listView


I have an establishment collection that I display in a combobox. One of the properties is "IsSelected", which allows me to select multiple items in a combobox.

        <ComboBox Name="CmbEtabTout" 
              ItemsSource="{Binding EtablissementsUtilisateur}"
              Grid.IsSharedSizeScope="True"
              Grid.Column="2" 
              Grid.ColumnSpan="3" 
              Grid.Row="2" 
              Height="25" 
              Width="250">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30" />
                        <ColumnDefinition SharedSizeGroup="AgentA" Width="auto" />
                        <ColumnDefinition Width="5" />
                        <ColumnDefinition SharedSizeGroup="AgentB" Width="auto" />
                    </Grid.ColumnDefinitions>
                    <CheckBox IsChecked="{Binding IsSelected}" Grid.Column="0"/>
                    <TextBlock Text="{Binding IdEtablissement}" Grid.Column="1"/>
                    <TextBlock Text="{Binding Nom}" Grid.Column="3"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

    <ListView x:Name="LVAgent"
    ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
    ItemsSource="{Binding Agents}" Grid.ColumnSpan="2" Margin="150,0,42,0" Grid.Column="2" Grid.Row="4" Grid.RowSpan="5" >
        <ListView.View>
            <GridView>
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsSelected}" 
                                              Command="{Binding DataContext.SelectAgentCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
                                              CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                    <CheckBox IsChecked="{Binding SelectAllAgents}"
                        IsEnabled="True"/>
                </GridViewColumn>
                <GridViewColumn Header="Matricule"
                    Width="110" 
                    DisplayMemberBinding="{Binding Matricule}"/>
                <GridViewColumn Header="Nom" 
                    Width="120"
                    DisplayMemberBinding="{Binding Nom}"/>
                <GridViewColumn Header="Prénom" 
                    Width="120" 
                    DisplayMemberBinding="{Binding Prenom}"/>

            </GridView>
        </ListView.View>
    </ListView>

My combobox collection :

        private ObservableCollection<Etablissement> _EtablissementsUtilisateur;
    public ObservableCollection<Etablissement> EtablissementsUtilisateur
    {
        get
        {
            return _EtablissementsUtilisateur;
        }
        set
        {
            if (value != _EtablissementsUtilisateur)
            {
                _EtablissementsUtilisateur = value;
                RaisePropertyChanged(nameof(EtablissementsUtilisateur));
            }
        }
    }

I'm trying to find out how to bind these comboboxes to refresh a list: if I choose three establishments, the list displays the agents of these three establishments. With a command maybe?

     <CheckBox IsChecked="{Binding IsSelected}" Grid.Column="0"/>

Look like this :

enter image description here

Since I already bind my checkbox with "IsSelected" (used for SelectAll), I don't know how to bind to refresh the list of Agent behind, when I check, without having to press a button like "validate".

Edit : My problem now is if I want to do something like this, for exemple :

       <CheckBox IsChecked="{Binding IsSelected}" Command="{Binding }" Grid.Column="0" />

I can only bind to the Etablissement Class and not to the ViewModel. (because of the itemSource of combobox i think)


Solution

  • the goal is, "when any checkbox is checked or unchecked, if I choose three establishments, the list displays the agents of these three establishments".

    "when any checkbox is checked or unchecked" => property changed event handler

    "if I choose three establishments" => if statement

    "the list displays the agents of these three establishments" => method call

    assuming Etablissement : INotifyPropertyChanged, we could add the event handler to each Etablissement.PropertyChanged. the other option is to add the handler to CheckBox.Checked and CheckBox.Unchecked.

    bonus: event handlers can be async, so if "method call" is async, you're right at home to await it, meaning your UI remains responsive and does not lock up.

    i would add the handlers inside a Loaded event for your UserControl or perhaps the ComboBox

    Loaded += delegate
    {
        PropertyChangedEventHandler propertyChanged = delegate
        {
            //if number of checked items != 3
                //return;
            //update agents
        };
        foreach (var etablissement in EtablissementsUtilisateur)
            etablissement.PropertyChanged += propertyChanged;
    }