我正在制作一个 MVVM WPF 应用程序,在这个应用程序中,我有一个带有我自己的特权项的 ListBox。
经过多年,我终于找到了一个解决方案,如何让选择与我的 ViewModel 同步。(您还需要在您的项目类中实现 IEquatable)
问题
现在我想将 ListBoxItems 设置为 CheckBoxes,这个问题有很多解决方案,但没有一个真正适合我的需求。
所以我想出了这个解决方案,因为我可以只将这种样式应用到我需要的 ListBoxes,而且我不必担心 DisplayMemberPath 或 Items 被设置为 CheckBox和ListBoxItems。
看法:
<ListBox Grid.Row="5" Grid.Column="1"
ItemsSource="{Binding Privileges}"
BehavExt:SelectedItems.Items="{Binding SelectedPrivileges}"
SelectionMode="Multiple"
DisplayMemberPath="Name"
Style="{StaticResource CheckBoxListBox}"/>
风格:
<Style x:Key="CheckBoxListBox"
TargetType="{x:Type ListBox}"
BasedOn="{StaticResource MetroListBox}">
<Setter Property="Margin" Value="5" />
<Setter Property="ItemContainerStyle"
Value="{DynamicResource CheckBoxListBoxItem}" />
</Style>
<Style x:Key="CheckBoxListBoxItem"
TargetType="{x:Type ListBoxItem}"
BasedOn="{StaticResource MetroListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<CheckBox IsChecked="{TemplateBinding Property=IsSelected}">
<ContentPresenter />
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
视图模型:
private ObservableCollection<Privilege> _privileges;
public ObservableCollection<Privilege> Privileges
{
get { return _privileges; }
set {
_privileges = value;
RaisePropertyChanged(() => Privileges);
}
}
private ObservableCollection<Privilege> _selectedPrivileges;
public ObservableCollection<Privilege> SelectedPrivileges
{
get { return _selectedPrivileges; }
set
{
_selectedPrivileges = value;
RaisePropertyChanged(() => SelectedPrivileges);
}
}
问题是这一行:
IsChecked="{TemplateBinding Property=IsSelected}"
它工作正常,但仅限于一个方向。当我在代码中添加一个项目时,SelectedPrivileges
它会显示为选中,但是当我在 GUI 中选中这个项目时,它不会做任何事情。(没有 CheckBox 样式它可以工作,所以这是因为 TemplateBinding 只能在一个方向上工作)
我怎样才能让它工作?我虽然关于触发器之类的东西,但我不知道如何做到这一点。