C# Wpf MVVM组合框,带有复选框并选中所有复选框

C# Wpf MVVM组合框,带有复选框并选中所有复选框,c#,wpf,xaml,mvvm,combobox,C#,Wpf,Xaml,Mvvm,Combobox,我有一个带有复选框的组合框,我想实现全选选项。 我在XAML中以以下方式执行此操作: <ComboBox Text="Select Industry" TextSearch.TextPath ="Industry" Name="industry" IsEditable="True" IsReadOnly="True" > <ComboBox.ItemsSource> <CompositeCollection>

我有一个带有复选框的组合框,我想实现全选选项。 我在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>
进入

<ComboBoxItem>
<CheckBox x:Name="allIndustry">All</CheckBox>
</ComboBoxItem>
但是,当我实现此更改时,单击“全选”不会更新我的组合框项目:

这是ViewModel的属性

 private ObservableCollection<IndustryFilter> _industryFilters;
        public ObservableCollection<IndustryFilter> IndustryFilters
        {
            get { return _industryFilters; }
            set
            {
                _industryFilters = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IndustryFilters"));
            }
        }
private observedcollection\u行业过滤器;
公共可观测收集行业过滤器
{
获取{return\u industryFilters;}
设置
{
_行业过滤器=价值;
房地产变更(即新的房地产变更开发者(“行业过滤器”);
}
}
这是XAML视图上部定义的源代码

<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源更新所有名为“industry”的ComboBox,并将“industry”复选框绑定到ViewModel?
如果没有完整的工作示例,要给出完整的工作示例并不容易

你可以用其他方法解决你的问题

您的
IndustryFilters
不应该是
observeablecollection
,而是这样一个对象的实例:

<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>
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"));
        }
    }
}
公共类行业过滤器:INotifyPropertyChanged{
私人(未经检查);;
公共卫生检查{
获取{return\u isAllChecked;}
设置{
_isAllChecked=值;
foreach(筛选器中的var筛选器){
filter.IsChecked=值;
}
财产变动(……);
}
}
公共可观测收集过滤器
{
获取{return\u industryFilters;}
设置
{
_行业过滤器=价值;
房地产变更(即新的房地产变更开发者(“行业过滤器”);
}
}
}
然后将
All
IsChecked
绑定到
IsAllChecked
属性

然后,您必须找到一种方法,将组合框的源更改为IndustryFilters.Filters


希望这有帮助。

在布鲁诺·阿尔梅达的帮助下,我成功地解决了这个问题

这是状态过滤器的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"));

            }
        }
私有ObservableCollection\u状态过滤器;
公共ObservableCollection状态筛选器
{
获取{return\u stateFilters;}
设置
{
_状态过滤器=值;
PropertyChanged(这是新的PropertyChangedEventArgs(“状态过滤器”);
}
}
私有布尔状态过滤器;
公共布尔状态过滤器
{
获取{return\u stateFilter;}
设置
{
_stateFilter=值;
ObservableCollection local=新的ObservableCollection();
foreach(StateFilters中的var过滤器)
{
filter.IsChecked=\u stateFilter;
本地。添加(过滤器);
}
StateFilters=本地;
PropertyChanged(这是新的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>

全部的

过滤器的更新是这样工作的,但是复选框本身没有更新,尽管我已经设置了,我现在想知道,如果我设置了正确的绑定,为什么复选框没有更新?您的IndustryFilter是否实现了InotifyProperty更改?是的,我已经使用您的想法解决了这个问题。。。谢谢如果您的StateFilter实现INotifyPropertyChanged,则不需要局部变量。是的,我确实更改了INotifyPropertyChanged,但捕获结果显示,当我仅更改列表中对象的属性IsChecked时,OberTableList上的设置器未设置。。。我想我可能会覆盖Equals方法,但是。。。我看到我已经得到了结果,因为我是WPF的新手-对于这样一个琐碎的任务(我更喜欢web开发)这个全选功能是一件痛苦的事情…在引入局部变量a之前使用的是:foreach(StateFilters中的var filter){StateFilters.IsChecked=\u stateFilter;},但setter没有被调用。您误解了。您有ObservableCollection。ObservableCollection实现INotifyPropertyChanged。但是,根据您的描述,StateFilter对象本身似乎没有实现INotifyPropertyChanged。是的,您是对的,它是从db对象派生的纯EntityFramework类
<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>