我正在尝试使用“全选”项目制作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="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);
}
}
}
}
设置测试数据:
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;
修改 使用以下代码替换CheckComboBox.cs中的 SelectAll DependencyProperty,但未输入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 (var item in checkComboBox.ComboBoxItems)
{
item.IsSelected = (bool) e.NewValue;
}
}
public bool SelectAll
{
get { return (bool) GetValue(SelectAllProperty); }
set { SetValue(SelectAllProperty, value); }
}
答案 0 :(得分:1)
最后想出了如何触发“SelectAll”属性。请注意:
<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); }
}
}
现在,我只需要弄清楚当取消选择其他项目时如何自动取消选中“全选”复选框。