Я искал эту тему и нашел несколько обсуждений.
Что мне не понравилось в этих реализациях, так это то, что они либо подразумевали специальный вид связанных данных (со свойством IsSelected), либо не имели нормальной поддержки клавиатуры.
CheckBox в списке - скорее декоративная вещь, нежели расширение функциональности, поэтому с ним следует обращаться соответствующим образом.
Я начал с этой милой и полезной статьи: http://www.gbogea.com/2010/01/02/mvvm-multiselect-listbox
Но я верю, что взлом View в пользу ViewModel - не совсем хорошая практика. Это ViewModel для адаптации к View и Model. Конечно, ИМХО.
Итак, я немного изменился и закончил с этим XAML:
<ListBox Name="checkboxList"
ItemsSource="{Binding Sports}"
Margin="0,5"
SelectionMode="Multiple">
<ListBox.ItemContainerStyle>
<Style>
<Setter Property="ListBoxItem.Background" Value="Transparent"/>
<Setter Property="ListBoxItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd"
SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected, Mode=TwoWay}"
Content="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Здесь выбор CheckBox синхронизирован с ListBoxItem.IsSelected, а ListBox не знает об особенностях связанных данных.
Это нормально.
Но есть ли способ добавить Select | Deselect All для ListBox, добавив еще один флажок в шаблон элемента управления? Использование только XAML.