【问题标题】:WPF: Get a ListBoxItem as CheckBox with a Template Style to synchronize with IsSelectedWPF:使用模板样式获取 ListBoxItem 作为 CheckBox 以与 IsSelected 同步
【发布时间】:2013-02-26 14:33:28
【问题描述】:

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

多年后,我终于找到了solution 如何让选择与我的 ViewModel 同步。 (您还需要在您的项目类中实现 IEquatable)

问题

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

所以我想出了这个解决方案,因为我只能将此样式应用于我需要的 ListBox,而且我不必担心 DisplayMemberPath 或 Items 被设置为 CheckBox 列表框项。

查看:

<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 只能在一个方向上工作)

如何让它工作?我虽然有类似触发器的东西,但我不知道如何实现这一点。

【问题讨论】:

  • 您是否尝试过将模式设置为两种方式并更新源触发器以更改属性?
  • 您不能将 TemplateBinding 设置为两种方式,并且正常的 Binding 将不起作用(或者至少我还没有找到使用模板访问 IsSelected 的方法)
  • 抱歉我错过了模板绑定
  • 谢谢。这对我很有帮助。我必须对链接的文章进行一些调整才能使用我的 ICollectionView。但一切都很好。

标签: c# wpf xaml checkbox listbox


【解决方案1】:

我相信您正在寻找的内容实际上非常简单。需要更改IsChecked属性绑定的绑定方式,如下:

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

应该可以的。

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

【讨论】:

  • 您不能将 TemplateBinding 设置为两种方式,并且普通的 Binding 不起作用(或者至少我还没有找到使用模板访问 IsSelected 的方法),但我m 到一个正常绑定的解决方案
  • 好吧,你不能做两种方式的 TemplateBinding,但感谢备忘单,我刚刚找到了我需要的东西 {Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Mode=TwoWay} 可以工作,因为它与 TemplateBinding 相同。如果你修改你的答案,我会给你功劳!谢谢!
猜你喜欢
  • 2011-02-05
  • 2010-12-25
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 2013-07-26
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多