简体   繁体   English

Wpf MVVM ComboBox带有复选框并选中所有复选框

[英]Wpf MVVM ComboBox with Checkboxes and Select all Checkbox

I have a ComboBox with CheckBoxes and I would like to implement Select All Option. 我有一个带有CheckBoxes的ComboBox,我想实现Select All Option。 I do this in the following way in the XAML: 我在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: 我使用上面的代码在视图中获得了此功能:

所有选定项组合框示例

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. 但是,这里的问题是,我曾经绑定了ViewModel属性IsChecked的IsChecked ComboBox属性,并且实施此解决方案后,我失去了此功能。

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. 将绑定更改为OneWayToSource,并从x:Name="allIndustry"更新复选框中的x:Name="allIndustry"我的选定项”。

I Should be able to do this only from the XAML View... 我应该只能从XAML视图执行此操作...

After that I would just bind my ComboBox to ViewModel property... 之后,我将ComboBox绑定到ViewModel属性...

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项目:

ComboBox全选失败

This is the property of the ViewModel 这是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 这是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>

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? 我如何从ComboBox.Item Source更新所有名为“ industry”的ComboBox,并保持“ industry”复选框绑定到ViewModel? Regards 问候

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

Then you bind the IsChecked of <CheckBox x:Name="allIndustry">All</CheckBox> to the IsAllChecked property. 然后,将<CheckBox x:Name="allIndustry">All</CheckBox>IsChecked绑定到IsAllChecked属性。

Then you will have to find a way to change the source of your ComboBox to IndustryFilters.Filters. 然后,您将必须找到一种将ComboBox的源更改为IndustryFilters.Filters的方法。

Hope this helps. 希望这可以帮助。

With the help of bruno.almeida I have managed to solve this 在bruno.almeida的帮助下,我设法解决了这个问题

This is the ViewModel property definition for the State filter - same as the Industry field i asked: 这是State过滤器的ViewModel属性定义-与我询问的Industry字段相同:

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: 这是XAML代码示例:

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM