Как-то так (использовал PropertyChanged.Fody, поэтому в коде нет явных вызовов OnPropertyChanged и OnIsSelectedChanged):
public class CalendarItem: INotifyPropertyChanged
{
public CalendarItem(Calendar owner) => Owner = owner;
public Calendar Owner { get; }
public bool IsSelected { get; set; }
void OnIsSelectedChanged() => Owner.UpdateSelection(this);
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Calendar : INotifyPropertyChanged
{
readonly ObservableCollection<CalendarItem> _items = new ObservableCollection<CalendarItem>();
public ICollectionView Items { get; }
public Calendar()
{
var dtf = CultureInfo.InvariantCulture.DateTimeFormat;
foreach(var s in Enumerable.Range(1,12).Select(n=>dtf.GetMonthName(n)))
_items.Add(new CalendarItem(this){Name = s});
Items = CollectionViewSource.GetDefaultView(_items);
}
public void UpdateSelection(CalendarItem selectedItem)
{
var selected = _items.Where(i => i.IsSelected).ToList();
SelectedItem = selected.Any() ? selectedItem : null;
Selection = selected.Any() ? selected.Select(i => i.Name).Aggregate((a, b) => $"{a}, {b}") : string.Empty;
}
public CalendarItem SelectedItem { get; set; }
public string Selection { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Разметка:
<Window.Resources>
<local:Calendar x:Key="Calendar" />
<DataTemplate DataType="{x:Type local:CalendarItem}" x:Key="CalendarItemTemplate">
<CheckBox
IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Content="{Binding Name, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="SelectionBoxTemplate">
<TextBlock
Text="{Binding RelativeSource={RelativeSource FindAncestor, ComboBox, 1}, Path=DataContext.Selection}" />
</DataTemplate>
<DataTemplate x:Key="CombinedTemplate">
<ContentPresenter
x:Name="Presenter"
Content="{Binding}"
ContentTemplate="{StaticResource CalendarItemTemplate}" />
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}"
Value="{x:Null}">
<Setter
TargetName="Presenter" Property="ContentTemplate"
Value="{StaticResource SelectionBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Window.DataContext>
<StaticResource ResourceKey="Calendar" />
</Window.DataContext>
<ComboBox
VerticalAlignment="Center"
Margin="10"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=OneWay}"
ItemTemplate="{StaticResource CombinedTemplate}" />