c# – WPF:使用模板样式获取ListBoxItem作为CheckBox,以与IsSelected同步

我正在制作一个MVVM
WPF应用程序,在这个应用程序中我有一个带有我自己的权限项的ListBox.

经过几年的努力,我终于找到了一个solution如何与我的ViewModel同步选择. (您还需要在项目类中实现IEquatable)

问题

现在我想将ListBoxItems设计为CheckBoxes,这个问题有很多解决方案,但没有一个真正符合我的需求.

所以我提出了这个解决方案,因为我只能将这种风格应用于我需要的ListBox,而且我不必担心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只能在一个方向上工作)

我如何让它工作?我虽然看起来像触发器,但我不知道如何实现这一目标.

最佳答案 我相信你所寻找的实际上非常简单.您需要更改IsChecked属性绑定的绑定模式,如下所示:

{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}

应该这样做.

这个以及基本上任何其他WPF绑定技巧都可以在这个优秀的cheat sheet上找到.

点赞