ユーザー定義の項目リストに加えて、「すべて選択」項目を含む 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); }
}