在WPF中绑定/触发“选择所有”-CheckBox ComboBoxItem [英] Binding/Triggering "Select all"-CheckBox ComboBoxItem in WPF

查看:376
本文介绍了在WPF中绑定/触发“选择所有”-CheckBox ComboBoxItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个WPF CustomControl CheckComboBox与一个选择所有项目除了用户定义的项目列表。当选择全选时,应相应地检查列表中的所有项目。我如何处理单击的全选项目?我已经尝试了很多东西,但是CheckComboBox.cs中的属性SelectAll从不输入。



这是我当前的代码。



Generic.xaml

 < Style TargetType ={x:Type local:CheckComboBox} > 
< Setter Property =Template>
< Setter.Value>
< ControlTemplate TargetType ={x:Type local:CheckComboBox}>
< ComboBox SelectedItem ={TemplateBinding SelectedItem}
SelectedValue ={TemplateBinding SelectedValue}
SelectedValuePath ={TemplateBinding SelectedValuePath}
DisplayMemberPath ={TemplateBinding DisplayMemberPath}
IsTextSearchEnabled ={TemplateBinding IsTextSearchEnabled}
ItemTemplate ={TemplateBinding ItemTemplate}
x:Name =InnerComboBox>

< ComboBox.Resources>
< ResourceDictionary>
< CheckBox x:Key =allItemContent =AllIsChecked ={Binding SelectAll,RelativeSource = {RelativeSource TemplatedParent},Mode = TwoWay}/>
< CollectionViewSource x:Key =itemsSource ={Binding ComboBoxItems,RelativeSource = {RelativeSource TemplatedParent},Mode = TwoWay}/>
< / ResourceDictionary>
< /ComboBox.Resources>

< ComboBox.ItemsSource>
< CompositeCollection>
< ComboBoxItem Content ={Binding Source = {StaticResource allItem}}/>
< CollectionContainer Collection ={Binding Source = {StaticResource items}}/>
< / CompositeCollection>
< /ComboBox.ItemsSource>

< / ComboBox>

< / ControlTemplate>
< /Setter.Value>
< / Setter>
< Setter Property =ItemTemplate>
< Setter.Value>
< DataTemplate>
< StackPanel Orientation =Horizo​​ntal>
< CheckBox IsChecked ={Binding IsSelected}Content ={Binding Text}VerticalAlignment =Center/>
< / StackPanel>
< / DataTemplate>
< /Setter.Value>
< / Setter>
< / Style>

CheckComboBox.cs

  public class CheckComboBox:ComboBox 
{
public class CheckComboBoxItem
{
public CheckComboBoxItem(bool isSelected,string text)
{
IsSelected = isSelected;
Text = text;
}
public bool IsSelected {get;组; }
public string Text {get;组; };
}

static CheckComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox),new FrameworkPropertyMetadata(typeof(CheckComboBox)
}

public static readonly DependencyProperty ComboBoxItemsProperty =
DependencyProperty.Register(ComboBoxItems,typeof(ObservableCollection< CheckComboBoxItem>),typeof(CheckComboBox),new PropertyMetadata(default(ObservableCollection< ; CheckComboBoxItem>)));

public ObservableCollection< CheckComboBoxItem> ComboBoxItems
{
get {return(ObservableCollection< CheckComboBoxItem>)GetValue(ComboBoxItemsProperty); }
set {SetValue(ComboBoxItemsProperty,value);} }
}

public static readonly DependencyProperty SelectAllProperty =
DependencyProperty.Register(SelectAll,typeof(bool),typeof(CheckComboBox),new PropertyMetadata );

public bool SelectAll
{
get {return(bool)GetValue(SelectAllProperty); }
set
{
foreach(ComboBoxItems中的var项)
{
item.IsSelected = value;
}
SetValue(SelectAllProperty,value);
}
}
}
}

设置测试数据:

  ObservableCollection< CheckComboBox.CheckComboBoxItem> checkComboBoxItems = new ObservableCollection< CheckComboBox.CheckComboBoxItem>(); 
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(false,Generation 0));
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(true,Generation 1));
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(false,Generation 2));
checkComboBox1.ComboBoxItems = checkComboBoxItems;

em> DependencyProperty在CheckComboBox.cs中使用以下代码,但未输入OnSelectAll。 SelectAll组合框由于某种原因不会触发绑定。

  public static readonly DependencyProperty SelectAllProperty = 
DependencyProperty.Register SelectAll,
typeof(bool),
typeof(CheckComboBox),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnSelectAll))) ;

private static void OnSelectAll(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
CheckComboBox checkComboBox =(CheckComboBox)d;
foreach(checkComboBox.ComboBoxItems中的var项)
{
item.IsSelected =(bool)e.NewValue;
}
}

public bool SelectAll
{
get {return(bool)GetValue(SelectAllProperty); }
set {SetValue(SelectAllProperty,value); }
}


解决方案

触发SelectAll属性。请注意:

 < ComboBoxItem> 
< CheckBox ... />
< / ComboBoxItem>

Generic.xaml

  ... 
< ComboBox.Resources>
< ResourceDictionary>
< CollectionViewSource x:Key =itemsSource ={Binding ItemsSource,RelativeSource = {RelativeSource TemplatedParent},Mode = TwoWay}/>
< / ResourceDictionary>
< /ComboBox.Resources>

< ComboBox.ItemsSource>
< CompositeCollection>
< ComboBoxItem>
< CheckBox Content =AllIsChecked ={Binding SelectAll,RelativeSource = {RelativeSource TemplatedParent},Mode = TwoWay}/>
< / ComboBoxItem>
< CollectionContainer Collection ={Binding Source = {StaticResource items}}/>
< / CompositeCollection>
< /ComboBox.ItemsSource>
...

CheckComboBox.cs

  public class CheckComboBox:ComboBox 
{
public class CheckComboBoxItem:ModelBase
{
public CheckComboBoxItem (bool isSelected,string text)
{
IsSelected = isSelected;
Text = text;
}

private bool _isSelected;
public bool IsSelected
{
get {return _isSelected; }
set {Set(()=> IsSelected,ref _isSelected,value); }
}

private string _text;
public string Text
{
get {return _text; }
set {Set(()=> Text,ref _text,value); }
}
}

static CheckComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox),new FrameworkPropertyMetadata(typeof(CheckComboBox))) ;
}

public static readonly DependencyProperty SelectAllProperty =
DependencyProperty.Register(SelectAll,
typeof(bool),
typeof(CheckComboBox),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnSelectAll)));

private static void OnSelectAll(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
CheckComboBox checkComboBox =(CheckComboBox)d;
IEnumerable< CheckComboBoxItem> items =(IEnumerable< CheckComboBoxItem>)checkComboBox.ItemsSource;
foreach(项目中的var项)
{
item.IsSelected =(bool)e.NewValue;
}
}

public bool SelectAll
{
get {return(bool)GetValue(SelectAllProperty); }
set {SetValue(SelectAllProperty,value); }
}
}

现在我只需要弄清楚如何自动取消选择另一个项目时取消选中全选复选框。


I'm trying to make a WPF CustomControl CheckComboBox with a "Select All" item in addition to a user defined list of items. When "Select All" is selected, all items in the list should be checked accordingly. How can I act to the "Select All" item being clicked? I have tried a lot of things, but the property "SelectAll" in the CheckComboBox.cs is never entered.

This is my current code.

Generic.xaml

<Style TargetType="{x:Type local:CheckComboBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CheckComboBox}">
                    <ComboBox SelectedItem="{TemplateBinding SelectedItem}"
                              SelectedValue="{TemplateBinding SelectedValue}"
                              SelectedValuePath="{TemplateBinding SelectedValuePath}"
                              DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
                              IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}"
                              ItemTemplate="{TemplateBinding ItemTemplate}"
                              x:Name="InnerComboBox" >

                        <ComboBox.Resources>
                            <ResourceDictionary>
                                <CheckBox x:Key="allItem" Content="All" IsChecked="{Binding SelectAll, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
                                <CollectionViewSource x:Key="items" Source="{Binding ComboBoxItems, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
                            </ResourceDictionary>
                        </ComboBox.Resources>

                        <ComboBox.ItemsSource>
                            <CompositeCollection>
                                <ComboBoxItem Content="{Binding Source={StaticResource allItem}}"/>
                                <CollectionContainer Collection="{Binding Source={StaticResource items}}" />
                            </CompositeCollection>
                        </ComboBox.ItemsSource>

                    </ComboBox>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Text}" VerticalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>

CheckComboBox.cs

   public class CheckComboBox : ComboBox
    {
        public class CheckComboBoxItem
        {
            public CheckComboBoxItem(bool isSelected, string text)
            {
                IsSelected = isSelected;
                Text = text;
            }
            public bool IsSelected { get; set; }
            public string Text { get; set; }
        }

        static CheckComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox), new FrameworkPropertyMetadata(typeof(CheckComboBox)));
        }

        public static readonly DependencyProperty ComboBoxItemsProperty =
            DependencyProperty.Register("ComboBoxItems", typeof (ObservableCollection<CheckComboBoxItem>), typeof (CheckComboBox), new PropertyMetadata(default(ObservableCollection<CheckComboBoxItem>)));

        public ObservableCollection<CheckComboBoxItem> ComboBoxItems
        {
            get { return (ObservableCollection<CheckComboBoxItem>) GetValue(ComboBoxItemsProperty); }
            set { SetValue(ComboBoxItemsProperty, value); }
        }

        public static readonly DependencyProperty SelectAllProperty =
            DependencyProperty.Register("SelectAll", typeof (bool), typeof (CheckComboBox), new PropertyMetadata(default(bool)));

        public bool SelectAll
        {
            get { return (bool) GetValue(SelectAllProperty); }
            set
            {
                foreach (var item in ComboBoxItems)
                {
                    item.IsSelected = value;
                }
                SetValue(SelectAllProperty, value);
            }
        }
    }
}

Setting test data:

ObservableCollection<CheckComboBox.CheckComboBoxItem> checkComboBoxItems = new ObservableCollection<CheckComboBox.CheckComboBoxItem>();
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(false, "Generation 0"));
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(true, "Generation 1"));
checkComboBoxItems.Add(new CheckComboBox.CheckComboBoxItem(false, "Generation 2"));
checkComboBox1.ComboBoxItems = checkComboBoxItems;

Edit: Replaced the SelectAll DependencyProperty in CheckComboBox.cs with the following code, but OnSelectAll is not entered. The SelectAll combobox does not trigger the binding for some reason.

public static readonly DependencyProperty SelectAllProperty =
        DependencyProperty.Register("SelectAll",
                    typeof (bool),
                    typeof (CheckComboBox),
                    new FrameworkPropertyMetadata(false,
                        FrameworkPropertyMetadataOptions.AffectsRender,
                        new PropertyChangedCallback(OnSelectAll)));

private static void OnSelectAll(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    CheckComboBox checkComboBox = (CheckComboBox)d;
    foreach (var item in checkComboBox.ComboBoxItems)
    {
        item.IsSelected = (bool) e.NewValue;
    }
}

public bool SelectAll
{
    get { return (bool) GetValue(SelectAllProperty); }
    set { SetValue(SelectAllProperty, value); }
}    

解决方案

Finally figured out how to trigger the "SelectAll" property. Notice the:

<ComboBoxItem>
    <CheckBox ... />
</ComboBoxItem>

Generic.xaml

...
<ComboBox.Resources>
    <ResourceDictionary>
        <CollectionViewSource x:Key="items" Source="{Binding ItemsSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
    </ResourceDictionary>
</ComboBox.Resources>

<ComboBox.ItemsSource>
    <CompositeCollection>
        <ComboBoxItem>
            <CheckBox Content="All" IsChecked="{Binding SelectAll, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
        </ComboBoxItem>
        <CollectionContainer Collection="{Binding Source={StaticResource items}}" />
    </CompositeCollection>
</ComboBox.ItemsSource>
...

CheckComboBox.cs

public class CheckComboBox : ComboBox
{
    public class CheckComboBoxItem : ModelBase
    {
        public CheckComboBoxItem(bool isSelected, string text)
        {
            IsSelected = isSelected;
            Text = text;
        }

        private bool _isSelected;
        public bool IsSelected 
        { 
            get { return _isSelected; }
            set { Set(() => IsSelected, ref _isSelected, value); }
        }

        private string _text;
        public string Text 
        { 
            get { return _text; }
            set { Set(() => Text, ref _text, value); }
        }
    }

    static CheckComboBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckComboBox), new FrameworkPropertyMetadata(typeof(CheckComboBox)));
    }

    public static readonly DependencyProperty SelectAllProperty =
        DependencyProperty.Register("SelectAll",
                                    typeof (bool),
                                    typeof (CheckComboBox),
                                    new FrameworkPropertyMetadata(false,
                                        FrameworkPropertyMetadataOptions.AffectsRender,
                                        new PropertyChangedCallback(OnSelectAll)));

    private static void OnSelectAll(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CheckComboBox checkComboBox = (CheckComboBox)d;
        IEnumerable<CheckComboBoxItem> items = (IEnumerable<CheckComboBoxItem>) checkComboBox.ItemsSource;
        foreach (var item in items)
        {
            item.IsSelected = (bool) e.NewValue;
        }
    }

    public bool SelectAll
    {
        get { return (bool) GetValue(SelectAllProperty); }
        set { SetValue(SelectAllProperty, value); }
    }
}

Now I just have to figure out how to automatically de-select the "Select All" check box when another item is de-selected.

这篇关于在WPF中绑定/触发“选择所有”-CheckBox ComboBoxItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆