继电器命令 命令参数

Relay Commands Command Parameter

我正在尝试在使用 C# 的小型 WPF 项目中使用 MVVM 原则。 我有一个 ListBox,其中填充了通过绑定回 ViewModel 创建的 CheckBoxes。我还有一个绑定到 CheckBoxes 的命令,并希望将 CheckBoxes Content 作为 CommandParameter 传递。我一直在寻找这样的东西:

<Binding ElementName="" Path="Content"/>

不幸的是,因为 CheckBoxes 是通过绑定创建的,所以我没有元素名称。

ListBox / ListBoxItem Style 的代码是这样的:

<Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}">
    <Setter Property="SelectionMode" Value="Multiple"></Setter>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
                <Setter Property="Margin" Value="2" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <CheckBox Command="{Binding SelectedItemCommand, Mode=OneWay, Source={StaticResource comd}}">
                                <CheckBox.CommandParameter>
                                    <MultiBinding Converter="{StaticResource cv}">
                                        <Binding ElementName="" Path="Content"/>
                                    <Binding ElementName="" Path="IsChecked"/>
                                    </MultiBinding>
                                </CheckBox.CommandParameter>
                                <ContentPresenter></ContentPresenter>
                            </CheckBox>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

它的实现是:

<ListBox Grid.Row="1" Style="{StaticResource CheckBoxListStyle}" Name="lstProducts" ItemsSource="{Binding stampInfo, Mode=OneWay, Source={StaticResource vmStamp}}" 
        DisplayMemberPath="Country" >
</ListBox>

最终我的目标是能够在文本框中显示所有选定项目的文本 Contents(在本例中为国家/地区),每个国家/地区以逗号分隔。我目前唯一缺少的是 Country.

如果您真的想以不同方式显示 数据项,请不要为 ListBoxItem 创建 ControlTemplate,请改用 DataTemplate,这正是它的目的。参见 Data Templating Overview

ListBox 中删除 DisplayMemberPath,因为您不能同时使用路径和自定义 DataTemplate。如果没有 DataTemplate,您只会设置此路径,但您想指定具体的 属性 或 属性 路径来显示。

<ListBox Grid.Row="1"
         Style="{StaticResource CheckBoxListStyle}" Name="lstProducts"
         ItemsSource="{Binding stampInfo, Mode=OneWay, Source={StaticResource vmStamp}}"/>

ControlTemplate 替换为 DataTemplate 作为 ItemTemplate。然后将 ContentCommandParameter 绑定到 属性 Country。数据上下文自动设置为绑定的数据项集合中的相应项。 IsChecked 属性 可以使用 RelativeSource 绑定,这是 CheckBox 本身。

<Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}">
   <Setter Property="SelectionMode" Value="Multiple"></Setter>
   <Setter Property="ItemContainerStyle">
      <Setter.Value>
         <Style TargetType="{x:Type ListBoxItem}" >
            <Setter Property="Margin" Value="2" />
         </Style>
      </Setter.Value>
   </Setter>
   <Setter Property="ItemTemplate">
      <Setter.Value>
         <DataTemplate>
            <CheckBox Content="{Binding Country}"
                      Command="{Binding SelectedItemCommand, Mode=OneWay, Source={StaticResource comd}}">
                <CheckBox.CommandParameter>
                    <MultiBinding Converter="{StaticResource cv}">
                        <Binding Path="Country"/>
                        <Binding Path="IsChecked" RelativeSource="{RelativeSource Self}"/>
                    </MultiBinding>
                </CheckBox.CommandParameter>
            </CheckBox>
         </DataTemplate>
      </Setter.Value>
   </Setter>
</Style>

另一种选择是创建具有 属性 的数据项,该数据项可以绑定到 CheckBoxIsChecked 属性。然后你可以在数据项的 setter 或例如单击执行命令的按钮,该命令会过滤视图模型中的绑定集合以查找选中的项目。