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

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

【问题讨论】:

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

标签: wpf xaml datatrigger


【解决方案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>

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

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

    <ListBox ItemContainerStyle="{DynamicResource ListBoxItemContainerStyle}" .../>
    
  2. 通过删除x:Key 使样式隐式。然后它将应用于包含它的资源字典范围内的所有ListBoxItem

    <Style TargetType="{x:Type ListBoxItem}">
    

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 2012-12-21
    • 2012-01-07
    • 2014-05-03
    • 2015-06-26
    • 2012-01-18
    • 2017-07-14
    • 2018-03-08
    • 2020-09-01
    相关资源
    最近更新 更多