C# WPF:获取一个带有模板样式的ListBoxItem作为复选框,以与IsSelected同步

C# WPF:获取一个带有模板样式的ListBoxItem作为复选框,以与IsSelected同步,c#,wpf,xaml,checkbox,listbox,C#,Wpf,Xaml,Checkbox,Listbox,我正在制作一个MVVM WPF应用程序,在这个应用程序中,我有一个带有我自己特权项的列表框 几年后,我终于找到了一个方法,让选择与我的ViewModel同步。(您还需要在item类中实现IEquatable) 问题 现在我想将ListBoxItems样式设置为复选框,对于这个问题有很多解决方案,但没有一个真正符合我的需要 因此,我提出了这个解决方案,因为我可以将这种样式仅应用于我需要的列表框,并且我不必担心DisplayMemberPath,也不必担心项目被设置为CheckBox和ListBox

我正在制作一个MVVM WPF应用程序,在这个应用程序中,我有一个带有我自己特权项的列表框

几年后,我终于找到了一个方法,让选择与我的ViewModel同步。(您还需要在item类中实现IEquatable)

问题

现在我想将ListBoxItems样式设置为复选框,对于这个问题有很多解决方案,但没有一个真正符合我的需要

因此,我提出了这个解决方案,因为我可以将这种样式仅应用于我需要的列表框,并且我不必担心DisplayMemberPath,也不必担心项目被设置为CheckBoxListBoxItems

视图:

它工作正常,但只在一个方向。在代码中将项目添加到我的
SelectedPrivileges
时,它将显示为选中,但在GUI中选中此项目时,它不会执行任何操作。(如果没有复选框样式,它可以工作,这是因为TemplateBinding只能在一个方向上工作)


我怎样才能让它工作?我一直在想触发器之类的东西,但我不知道如何做到这一点。

我相信你想要的其实很简单。您需要更改
IsChecked
属性绑定的绑定模式,如下所示:

{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}
应该这样做


这一点和其他WPF绑定技巧基本上都可以在这个优秀的网站上找到。

您是否尝试过将模式设置为双向,并将UpdateSourceRigger设置为属性更改?您无法将TemplateBinding设置为双向,而普通绑定将无法工作(或者至少我还没有找到使用模板访问IsSelected的方法)哦,对不起,我错过了模板。谢谢。这对我很有帮助。我不得不对链接文章进行一些调整,以使用我的ICollectionView。但是一切都很好。你不能将TemplateBinding设置为双向,普通绑定也不起作用(或者至少我还没有找到一种方法来访问IsSelected,否则使用模板),但我可以用普通绑定解决问题OK,你不能做双向TemplateBinding,但多亏了备忘单,我找到了我需要的
{Binding RelativeSource={RelativeSource TemplatedParent},Path=IsSelected,Mode=TwoWay}
将起作用,因为它与TemplateBinding完全相同。如果您修改您的答案,我将给予您奖励!谢谢!
<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}"
{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay}