问题描述
在我的场景中,我有一个 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
类型的项目定义了触发器。对于这些项目,我想更改模板的某些方面,因此我使用 TargetName
上的 Setter
来更改 FontWeight
的 TextBlock
(在实际代码中我更改多个元素的多个属性)。但我也想更改整个项目的 ContextMenu
。为此,我使用了 Setter
without TargetName
和属性 ContextMenu
。
以上工作不知何故。如果您运行此程序并右键单击“事物 2”,您将看到 BMenu
。但是这是如何工作的? Setter
应用于什么对象? DataTemplate
没有 ContextMenu
属性。
我问这个不仅仅是出于好奇。我希望所有其他类型的项目(A
和 C
)都使用 DefaultMenu
。这应该是默认值,DataTrigger
会为 B
项覆盖它。但此时我什至不知道我在 Setter
-ing 什么对象,所以我不知道在哪里或如何设置这个默认值。
解决方法
Setter 应用于什么对象?
它应用于包装 ContentPresenter
源集合中的每个元素的 Things
项容器。
您可以使用 ContextMenu
设置默认 ItemContainerStyle
:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="ContextMenu" Value="{StaticResource DefaultMenu}"/>
</Style>
</ItemsControl.ItemContainerStyle>