0
votes

I have a ComboBox with CheckBoxes and I would like to implement Select All Option. I do this in the following way in the XAML:

<ComboBox Text="Select Industry"  TextSearch.TextPath ="Industry"  Name="industry"  IsEditable="True" IsReadOnly="True" >
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem>
                <CheckBox x:Name="allIndustry">All</CheckBox>
            </ComboBoxItem>
            <CollectionContainer Collection="{Binding Source={StaticResource industrySource}}"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Name="industry" IsChecked="{Binding ElementName=allIndustry, Path=IsChecked, Mode=OneWay}" Content="{Binding Industry}" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

I get this functionality in the view using the above code:

All Selected Items ComboBox example

But, the issue here is that I used to Bind my IsChecked ComboBox property of the ViewModel Property IsChecked , and implementing this solution I lost this feature.

I would like to move the line

IsChecked="{Binding ElementName=allIndustry, Path=IsChecked, Mode=OneWay}"

Into the

<ComboBoxItem>
<CheckBox x:Name="allIndustry">All</CheckBox>
</ComboBoxItem>

Change the binding to OneWayToSource, and update from the x:Name="allIndustry" my Selected Items in the CheckBox.

I Should be able to do this only from the XAML View...

After that I would just bind my ComboBox to ViewModel property...

It would look like this:

<ComboBox Text="Select Industry"  TextSearch.TextPath ="Industry"  Name="industry"  IsEditable="True" IsReadOnly="True" >
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem>
                <CheckBox x:Name="allIndustry" IsChecked="{Binding ElementName=industry, Path=IsChecked, Mode=OneWayToSource}">All</CheckBox>
            </ComboBoxItem>
            <CollectionContainer Collection="{Binding Source={StaticResource industrySource}}"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox Name="industry" IsChecked="{Binding IsChecked}" Content="{Binding Industry}" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

But when I implement this change clicking the Select All does not update my ComboBox Items:

ComboBox Select All fails

This is the property of the ViewModel

 private ObservableCollection<IndustryFilter> _industryFilters;
        public ObservableCollection<IndustryFilter> IndustryFilters
        {
            get { return _industryFilters; }
            set
            {
                _industryFilters = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IndustryFilters"));
            }
        }

And this is the Source defined in the upper part of the XAML view

<UserControl x:Class="Digital_Data_House_Bulk_Mailer.View.MailView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Digital_Data_House_Bulk_Mailer.View"
             xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
             xmlns:model="clr-namespace:Digital_Data_House_Bulk_Mailer.ViewModel"
             mc:Ignorable="d" 
             HorizontalAlignment="Stretch"
             VerticalAlignment="Stretch"
             HorizontalContentAlignment="Stretch"
             VerticalContentAlignment="Stretch"
             >
    <UserControl.Resources>

        <CollectionViewSource x:Key="industrySource" Source="{Binding IndustryFilters}"/>

    </UserControl.Resources>

How to I manage to update All the ComboBoxes named "industry" from the ComboBox.Item Source and keep the "industry" checkbox bound to the ViewModel? Regards

2

2 Answers

0
votes

Without a full working example isn't easy to give a full working example.

You can solve your problem using other approach.

Your IndustryFilters shouldn't be an ObservableCollection<IndustryFilter> but an instance of an object like this:

public class IndustryFilters : INotifyPropertyChanged {
    private _isAllChecked;

    public IsAllChecked {
        get {return _isAllChecked;}
        set{
            _isAllChecked = value;

            foreach(var filter in Filters) { 
                filter.IsChecked = value;
            }

            PropertyChanged(...);
        }
    }

    public ObservableCollection<IndustryFilter> Filters
    {
        get { return _industryFilters; }
        set
        {
            _industryFilters = value;
            PropertyChanged(this, new propertyChangedEventArgs("IndustryFilters"));
        }
    }
}

Then you bind the IsChecked of <CheckBox x:Name="allIndustry">All</CheckBox> to the IsAllChecked property.

Then you will have to find a way to change the source of your ComboBox to IndustryFilters.Filters.

Hope this helps.

0
votes

With the help of bruno.almeida I have managed to solve this

This is the ViewModel property definition for the State filter - same as the Industry field i asked:

private ObservableCollection<StateFilter> _stateFilters;
        public ObservableCollection<StateFilter> StateFilters
        {
            get { return _stateFilters; }
            set
            {
                _stateFilters = value;
                PropertyChanged(this, new PropertyChangedEventArgs("StateFilters"));
            }
        }

        private bool _stateFilter;
        public bool StateFilter
        {
            get { return _stateFilter; }
            set
            {
                _stateFilter = value;

                ObservableCollection<StateFilter> local = new ObservableCollection<StateFilter>();

                foreach (var filter in StateFilters)
                {
                    filter.IsChecked = _stateFilter;
                    local.Add(filter);

                }
                StateFilters = local;

                PropertyChanged(this, new PropertyChangedEventArgs("StateFilter"));

            }
        }

This is the XAML code example:

Resources:

ComboBox:

<ComboBox Text="Select State"  TextSearch.TextPath ="State"  Name="state"  IsEditable="True" IsReadOnly="True" >

    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem >
                <CheckBox  Name="all" IsChecked="{Binding StateFilter}">All</CheckBox>
            </ComboBoxItem>
            <CollectionContainer Collection="{Binding Source={StaticResource stateSource}}"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Name="chkTask" IsChecked="{Binding IsChecked}"  Content="{Binding State}" ></CheckBox>
        </DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>