当没有给出 TargetName 时,DataTemplate.Triggers 中的设置器在哪里应用?

Where are Setters in DataTemplate.Triggers applied when no TargetName is given?

在我的场景中,我有一个 ItemsControl,其中 DataTemplate 需要根据项目的属性以几种方式进行更改。需要更改的内容之一是该项目的上下文菜单。

我把这个例子放在一起来说明我的情况。采取以下类:

Class MainWindow
    Public Property Things As New List(Of Thing) From {New Thing With {.Name = "Thing 1", .Type = ThingType.A},
                                                       New Thing With {.Name = "Thing 2", .Type = ThingType.B},
                                                       New Thing With {.Name = "Thing 3", .Type = ThingType.C}}
End Class

Public Class Thing
    Public Property Name As String
    Public Property Type As ThingType
End Class

Public Enum ThingType
    A
    B
    C
End Enum

Thing 有一些数据要显示 (Name),还有一些应该影响模板 (Type)。

现在采取以下 XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:VBTest"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Window.Resources>
        <ContextMenu x:Key="DefaultMenu">
            <MenuItem Header="A or C"/>
        </ContextMenu>
        <ContextMenu x:Key="BMenu">
            <MenuItem Header="B Only"/>
        </ContextMenu>
    </Window.Resources>

    <ItemsControl ItemsSource="{Binding Things}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="local:Thing">
                <TextBlock Name="Title" Text="{Binding Name}"/>

                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Type}" Value="B">
                        <Setter TargetName="Title" Property="FontWeight" Value="Bold"/>
                        <Setter Property="ContextMenu" Value="{StaticResource BMenu}"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>    
</Window>

DataTemplate.Triggers 中,我为 B 类型的项目定义了一个触发器。对于这些项目,我想更改模板的某些方面,所以我在 Setter 上使用 TargetName 来更改 TextBlockFontWeight(在实际代码中我更改多个元素的多个属性)。但我也想更改整个项目的 ContextMenu。为此,我使用 Setter without TargetName 和 属性 ContextMenu.

以上 以某种方式工作 。如果您 运行 并右键单击“Thing 2”,您会看到 BMenu。但是这是如何工作的呢? Setter 应用于什么对象? DataTemplate 没有 ContextMenu 属性.

我问这个不仅仅是出于好奇。我希望所有其他类型的项目(AC)都使用 DefaultMenu。这应该是默认设置,DataTrigger 会覆盖 B 项目。但我什至不知道我现在 Setter-ing 是什么对象,所以我不知道在哪里或如何设置这个默认值。

What object is the Setter being applied to?

它应用于包装 Things 源集合中每个元素的 ContentPresenter 项目容器。

您可以使用 ItemContainerStyle:

设置默认值 ContextMenu
<ItemsControl.ItemContainerStyle>
    <Style TargetType="ContentPresenter">
        <Setter Property="ContextMenu" Value="{StaticResource DefaultMenu}"/>
    </Style>
</ItemsControl.ItemContainerStyle>