Wpf带有Checkbox的MVVM ComboBox并选择所有Checkbox

时间:2018-05-09 09:38:50

标签: c# wpf xaml mvvm combobox

我有一个带CheckBoxes的ComboBox,我想实现Select All Option。 我在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>

我使用上面的代码在视图中获得此功能:

All Selected Items ComboBox example

但是,这里的问题是我曾经将ViewModel Property IsChecked的IsChecked ComboBox属性绑定,并且实现了这个解决方案我失去了这个功能。

我想移动

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

进入

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

更改绑定到OneWayToSource,并从x:Name="allIndustry"更新 我在CheckBox中选择的项目。

我应该只能从XAML View ...

执行此操作

之后我会将我的ComboBox绑定到ViewModel属性......

看起来像这样:

<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>

但是当我实现此更改时,单击Select All不会更新我的ComboBox项目:

ComboBox Select All fails

这是ViewModel的属性

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

这是在XAML视图上部定义的Source

<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>

如何设置更新ComboBox.Item Source中名为“industry”的所有组合框并保持“行业”复选框绑定到ViewModel? 此致

2 个答案:

答案 0 :(得分:0)

如果没有一个完整的工作示例,就不容易给出一个完整的工作示例。

您可以使用其他方法解决问题。

您的IndustryFilters不应该是ObservableCollection<IndustryFilter>,而是这样的对象的实例:

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"));
        }
    }
}

然后将IsChecked的{​​{1}}绑定到<CheckBox x:Name="allIndustry">All</CheckBox>属性。

然后,您必须找到一种方法将ComboBox的源代码更改为IndustryFilters.Filters。

希望这有帮助。

答案 1 :(得分:0)

在bruno.almeida的帮助下,我设法解决了这个问题

这是状态过滤器的ViewModel属性定义 - 与我提出的行业字段相同:

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"));

            }
        }

这是XAML代码示例:

资源:

                             

组合框:

<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>