如何将参数传递给 DataTrigger?

Posted

技术标签:

【中文标题】如何将参数传递给 DataTrigger?【英文标题】:How can I pass a parameter to a DataTrigger? 【发布时间】:2021-10-01 03:43:48 【问题描述】:

我有一个通过ItemsControl 显示的内容列表,其中每个项目基本上都是一张可以点击的卡片。有没有办法可以将参数传递给 DataTrigger 以显示是否点击了卡片,如果点击了卡片,请将 Background 设置为另一种颜色?

【问题讨论】:

应该有一个视图模型项属性来控制设置的背景。要么直接绑定背景,要么通过带有绑定到该属性的 DataTrigger 设置它。 @Clemens 所以我应该在我的视图模型内的列表中的每个项目中添加一个“IsSelected”属性? 为了区分选中的item和未选中的item,当然这个item必须有一些属性。对于您的任务,除此之外,最好使用 ListBox 而不是 ItemsControl。它已经实现了所选项目的选择并在 SelectedItem 属性(或 SelectedItems 用于多选模式)中获取它。 【参考方案1】:

[...] 显示卡片是否被点击以及是否被点击 [...]

您创建了卡片视图并希望它们可以选择。 ItemsControl 不支持选择,但有一个名为 Selector 的控件派生自 ItemsControl,它是需要选择的项目控件的 abstract 基本类型。它的衍生产品包括ListBoxListView,它们具有开箱即用的选择和突出显示功能。换句话说,不要重新发明***,已经有更合适的控件满足你的要求了。

派生自Selector 的类型包含SelectedIndexSelectedItemSelectedValue 的依赖属性,这使您可以轻松绑定它们并创建触发器。还有一个附加属性 IsSelected 用于项目容器,这正是您根据单击或选定的项目更改 Background 或任何其他属性所需的。

下面我将向您展示如何自定义ListBox项目的外观。您可以对 ListView. 执行相同操作。您可以提取 ListBoxItem using Blend or Visual Studio 的默认样式和模板。

正如您在下面看到的,有一些画笔、一个焦点视觉效果以及带有控制模板和触发器的样式。调整此样式以满足您所需的设计。查找绑定IsSelected 属性的触发器。

<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
<Style x:Key="FocusVisual">
   <Setter Property="Control.Template">
      <Setter.Value>
         <ControlTemplate>
            <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="DynamicResource x:Static SystemColors.ControlTextBrushKey"/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>
<Style x:Key="ListBoxItemContainerStyle" TargetType="x:Type ListBoxItem">
   <Setter Property="SnapsToDevicePixels" Value="True"/>
   <Setter Property="Padding" Value="4,1"/>
   <Setter Property="HorizontalContentAlignment" Value="Binding HorizontalContentAlignment, RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"/>
   <Setter Property="VerticalContentAlignment" Value="Binding VerticalContentAlignment, RelativeSource=RelativeSource AncestorType=x:Type ItemsControl"/>
   <Setter Property="Background" Value="Transparent"/>
   <Setter Property="BorderBrush" Value="Transparent"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="FocusVisualStyle" Value="StaticResource FocusVisual"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="x:Type ListBoxItem">
            <Border x:Name="Bd" Background="TemplateBinding Background" BorderThickness="TemplateBinding BorderThickness" BorderBrush="TemplateBinding BorderBrush" Padding="TemplateBinding Padding" SnapsToDevicePixels="true">
               <ContentPresenter HorizontalAlignment="TemplateBinding HorizontalContentAlignment" SnapsToDevicePixels="TemplateBinding SnapsToDevicePixels" VerticalAlignment="TemplateBinding VerticalContentAlignment"/>
            </Border>
            <ControlTemplate.Triggers>
               <MultiTrigger>
                  <MultiTrigger.Conditions>
                     <Condition Property="IsMouseOver" Value="True"/>
                  </MultiTrigger.Conditions>
                  <Setter Property="Background" TargetName="Bd" Value="StaticResource Item.MouseOver.Background"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="StaticResource Item.MouseOver.Border"/>
               </MultiTrigger>
               <MultiTrigger>
                  <MultiTrigger.Conditions>
                     <Condition Property="Selector.IsSelectionActive" Value="False"/>
                     <Condition Property="IsSelected" Value="True"/>
                  </MultiTrigger.Conditions>
                  <Setter Property="Background" TargetName="Bd" Value="StaticResource Item.SelectedInactive.Background"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="StaticResource Item.SelectedInactive.Border"/>
               </MultiTrigger>
               <MultiTrigger>
                  <MultiTrigger.Conditions>
                     <Condition Property="Selector.IsSelectionActive" Value="True"/>
                     <Condition Property="IsSelected" Value="True"/>
                  </MultiTrigger.Conditions>
                  <Setter Property="Background" TargetName="Bd" Value="StaticResource Item.SelectedActive.Background"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="StaticResource Item.SelectedActive.Border"/>
               </MultiTrigger>
               <Trigger Property="IsEnabled" Value="False">
                  <Setter Property="TextElement.Foreground" TargetName="Bd" Value="DynamicResource x:Static SystemColors.GrayTextBrushKey"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

将这些资源移动到您想要使用它们的控件范围内的资源字典中,或者简单地将它们复制到应用程序资源中以使其全局可用。为了应用样式,您有两种选择。

    使用x:Key 并在每个ListBox 中将它们引用为ItemContainerStyle

    <ListBox ItemContainerStyle="DynamicResource ListBoxItemContainerStyle" .../>
    

    通过删除x:Key 使样式隐式。然后它将应用于包含它的资源字典范围内的所有ListBoxItem

    <Style TargetType="x:Type ListBoxItem">
    

【讨论】:

以上是关于如何将参数传递给 DataTrigger?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SwiftUI 将参数传递给 Button 的操作

如何将多个重复的参数传递给 CUDA 内核

jQuery UI 问题。如何将参数传递给函数

如何将参数传递给配置单元视图,以便视图根据传递的内容进行更改?

如何通过 JCL 将参数传递给 REXX 程序

如何将条目参数传递给 Xamarin MVVM 视图模型