我正在尝试使用祖先的资源中的样式对象在
这是我的控件的XAML,包括一个
值得注意的是,我不希望直接在 DataTemplate 的 Hyperlink 上设置不同的颜色。这是因为该模板将被许多不同的 ItemsControl 对象使用,其中大部分将在白色背景上使用标准的超链接颜色(请注意,上面的 XAML 中有一个红色背景)。简而言之,我不希望 DataTemplate 知道它所使用的控件的任何信息。模板控件的样式应该只过滤到它。那么,有人能告诉我为什么样式没有过滤下来以及我该怎么做才能解决它吗?谢谢。更新:由于我无法使 Pavlo 的答案在我的生产应用程序中起作用,因此我后来在一个单独的测试应用程序中尝试了它。该应用程序是一个 WinForms 应用程序,主窗体除了包含一个 ElementHost 外,什么都没有,ElementHost 本身包含一个简单的 WPF 用户控件。以下是它的 XAML:
如上所述,这会生成一个
可以通过在
简而言之,它没有起作用,因此我希望得到其他建议/更正。 :(
更新2: 由于Pavlo提供了另一种解决方案,现在它确实起作用了。 :)
Hyperlink
上设置Foreground
颜色,但没有任何效果。我甚至使用了更改超链接前景色而不失去悬停颜色中的BasedOn
提示,但没有任何区别 - 我仍然得到一个蓝色的超链接,在悬停时变成红色。这是我的控件的XAML,包括一个
ItemsControl
,其项目使用超链接显示:<StackPanel Background="Red" TextElement.Foreground="White">
<StackPanel.Resources>
<Style TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}">
<Setter Property="Foreground" Value="Yellow"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock>Data import errors</TextBlock>
<ItemsControl ItemsSource="{Binding Errors}"/>
</StackPanel>
而ItemsControl
中的项目将使用以下DataTemplate
:
<DataTemplate DataType="{x:Type Importer:ConversionDetailsMessage}">
<TextBlock>
<Run Text="{Binding Message, Mode=OneTime}"/>
<Hyperlink Command="Common:ImportDataCommands.ExplainConversionMessage" CommandParameter="{Binding}">
<Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
值得注意的是,我不希望直接在 DataTemplate 的 Hyperlink 上设置不同的颜色。这是因为该模板将被许多不同的 ItemsControl 对象使用,其中大部分将在白色背景上使用标准的超链接颜色(请注意,上面的 XAML 中有一个红色背景)。简而言之,我不希望 DataTemplate 知道它所使用的控件的任何信息。模板控件的样式应该只过滤到它。那么,有人能告诉我为什么样式没有过滤下来以及我该怎么做才能解决它吗?谢谢。更新:由于我无法使 Pavlo 的答案在我的生产应用程序中起作用,因此我后来在一个单独的测试应用程序中尝试了它。该应用程序是一个 WinForms 应用程序,主窗体除了包含一个 ElementHost 外,什么都没有,ElementHost 本身包含一个简单的 WPF 用户控件。以下是它的 XAML:
<UserControl x:Class="DataTemplateStyling.StylingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:DataTemplateStyling="clr-namespace:DataTemplateStyling"
x:Name="root" Loaded="StylingViewLoaded">
<UserControl.Resources>
<Style x:Key="MyDefaultHyperlinkStyle" BasedOn="{StaticResource {x:Type Hyperlink}}"/>
<DataTemplate DataType="{x:Type DataTemplateStyling:ImportMessage}">
<DataTemplate.Resources>
<Style TargetType="{x:Type Hyperlink}"
BasedOn="{StaticResource MyDefaultHyperlinkStyle}"/>
</DataTemplate.Resources>
<TextBlock>
<Run Text="{Binding Message, Mode=OneTime}"/>
<Hyperlink NavigateUri="{Binding HelpLink.Item1}">
<Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</UserControl.Resources>
<Grid DataContext="{Binding ElementName=root}">
<StackPanel Background="Red" TextElement.Foreground="White">
<StackPanel.Resources>
<Style x:Key="MyDefaultHyperlinkStyle" TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}">
<Setter Property="Foreground" Value="Yellow"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock>Data import errors</TextBlock>
<ItemsControl ItemsSource="{Binding Messages}"/>
</StackPanel>
</Grid>
</UserControl>
如上所述,这会生成一个
InvalidOperationException
,指出“只能基于目标类型为基本类型'IFrameworkInputElement'的样式”。可以通过在
UserControl.Resources
元素内部的Style
定义中立即放置TargetType =“Hyperlink”
来解决此问题。然而,虽然消息正在显示,但它们的链接部分仍具有默认的蓝色超链接样式:简而言之,它没有起作用,因此我希望得到其他建议/更正。 :(
更新2: 由于Pavlo提供了另一种解决方案,现在它确实起作用了。 :)