考虑这个(经过编辑的)Style
,它是为 Button
设计的,它的 Content
是一个 String
:
<Style x:Key="Test" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel>
<TextBlock x:Name="text" Text="{TemplateBinding Content}" />
<TextBlock x:Name="demo" Text="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}">
<DataTrigger.Value>
<system:String>Test</system:String>
</DataTrigger.Value>
<Setter TargetName="test" Property="Foreground" Value="Red" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此示例的目的是在按钮文本等于单词“Test”1 时将其变为红色。但它不起作用,因为触发器的 TemplatedParent
绑定(bind)解析为 null 而不是 Button
应用了 Style
。但是,名为“demo”的 TextBlock
将按预期将其 Text
设置为“System.Windows.Controls.Button: [ButtonText]”,这意味着 TemplatedParent
在该级别正常工作。为什么它在 DataTrigger
中不起作用?
1 我知道还有其他方法可以实现这一点,但我想了解为什么绑定(bind)无法按我预期的方式工作。
最佳答案
ControlTemplate.Triggers
中的
TemplatedParent
不是您所期望的。在触发器内部,它实际上引用了 Button.TemplatedParent
。因此,如果您在模板中创建那个按钮,它只会是非空的。您不会在模板内创建按钮,因此在您的情况下它为空。现在考虑这个 xaml:
<Window.Resources>
<Style x:Key="Test"
TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel>
<TextBlock x:Name="text"
Text="dummy" />
<TextBlock x:Name="demo"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}">
<DataTrigger.Value>
<system:String>Test</system:String>
</DataTrigger.Value>
<Setter TargetName="text"
Property="Foreground"
Value="Red" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Test2" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Button Style="{StaticResource Test}"></Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<!--<Button Content="Test" Style="{StaticResource Test}"/>-->
<ContentControl Style="{StaticResource Test2}" Content="Test" />
</Grid>
在这里,我重新制作了 ContentControl
模板,并在模板内部使用了 button 和您的模板。如果运行此代码,您将看到红色的“虚拟”文本,因为 Button.TemplatedParent
现在是 ContentControl
,并且它具有 Content
等于“测试”,这证实了我上面所说的。
现在回到您的问题:只需将 RelativeSource TemplatedParent
更改为 RelativeSource Self
(无需将 DataTrigger
更改为 Trigger
) - 这个会引用你的 Button。
关于c# - 在 ControlTemplate 的 DataTrigger 中使用时,TemplatedParent 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36896963/