XAML WPF:从 DataTemplate DataTrigger 设置 AncestorType 的背景属性

问题描述 投票:0回答:1

我将 WPF 与 ListView 一起使用(我可以使用 ListBox,问题仍然相同)。

我的 ListViewItem 具有自定义样式,模型具有 DataTemplate。我想使用 DataTemplate 上的 DataTrigger 更改 ListViewItem 的背景颜色。

有没有办法在 DataTemplate 上创建 DataTrigger,并让它以 ListViewItem 的 AncestorType 为目标来设置其背景?

下面是我的代码的简化版本。

这是我的模型(

ObservableObject
实现了
INotifyPropertyChanged
)。 对于上下文,它是读取的 RFID 标签,并且
SeenRecently
布尔值将指示该标签在最后一秒内被看到。当此属性为 true 时,我希望将 ListViewItem 背景颜色设置为“绿色”。

public class TagEntry : ObservableObject
{
  private string? serialNumber;

  public string? SerialNumber
  {
    get { return serialNumber; }
    set { SetProperty(ref serialNumber, value); }
  }

  private string? tagType;

  public string? TagType
  {
    get { return tagType; }
    set { SetProperty(ref tagType, value); }
  }

  private bool seenRecently;

  public bool SeenRecently
  {
    get { return seenRecently; }
    set { SetProperty(ref seenRecently, value); }
  }
}

这是我的

ListViewItem
风格(为了简洁删除了一些 Setter)。它有 2 个触发器,这是有意义的,因为
IsSelected
IsMouseOver
是在
ListViewItem
上找到的属性。

第三个触发器,用于我的数据模型上的

SeenRecently
属性来设置背景。 这确实有效,但现在我将此样式与我的数据模型耦合,如果我想在其他数据模型中重新使用此样式怎么办?

<Style x:Key="myItemContainerStyle" 
       TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="Beige"/>
            <Setter Property="BorderBrush" Value="OrangeRed"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="MediumPurple"/>
        </Trigger>
        <!-- This here works, but i'm now coupling my ListViewItem Style, with my Model -->
        <DataTrigger Binding="{Binding SeenRecently}" Value="True">
            <Setter Property="Background" Value="Green"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

这是我的 DataTemplate,这是放置 DataTrigger 的有意义的地方,但我不知道如何/是否可以定位

ListViewItem
类型的祖先来从这里设置其背景。

    <DataTemplate x:Key="TagTypeDataTemplate" DataType="model:TagEntry">
        <Grid Grid.Column="1" Margin="4">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="{Binding SerialNumber}" FontSize="24" FontWeight="SemiBold"/>
            <TextBlock Grid.Row="1" Text="{Binding TagType}" FontSize="18"/>
        </Grid>
    </DataTemplate>

这是示例图像。鼠标悬停时为紫色背景,

SeenRecently
项目为绿色。 Example of ListViewItems Showing changed background. 也许我的想法是错误的,也许我应该有一个专门针对我的数据模型的特殊
<Style TargetType="ListViewItem">

wpf xaml datatemplate datatrigger
1个回答
0
投票

经过一番尝试后,我认为对我来说最好的选择是为我的 ListViewItem 创建一个基本样式。然后为我的模型创建一个子样式,以触发更改。

我可以轻松地重复使用基本样式,并为我想要触发更改的任何其他模型创建一个新的小样式。

    <Style x:Key="TagEntryListViewContainerStyle" 
           TargetType="ListViewItem" 
           BasedOn="{StaticResource BaseListViewContainerStyle}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(model:TagEntry.SeenRecently)}" Value="True">
                <Setter Property="Background" Value="LightGreen"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
© www.soinside.com 2019 - 2024. All rights reserved.