Mal*_*oss 7 wpf xaml styles datatemplate hyperlink
我尝试使用祖先的对象设置Foreground颜色,但它没有任何效果.我甚至使用了更改超链接前景的提示而没有丢失悬停颜色,但它没有任何区别 - 我仍然得到一个悬停时为红色的蓝色超链接.HyperlinkStyleResourcesBasedOn
这是我的控件的XAML,包括ItemsControl使用超链接显示其项目的XAML :
<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>
Run Code Online (Sandbox Code Playgroud)
而且这些项目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>
Run Code Online (Sandbox Code Playgroud)
值得一提的,那就是,我不想只是上直接设置不同颜色Hyperlink的DataTemplate.这是因为模板将被许多不同的ItemsControl对象使用,其中大部分将在白色背景上,因此可以使用标准的超链接颜色.(请注意,上面XAML中的那个具有红色背景.)
简而言之,我不希望DataTemplate它对使用它的控件有任何了解.模板控件的样式应该只过滤到它.
所以...有谁能告诉我为什么风格没有过滤掉我可以做些什么来解决它?
谢谢.
更新:
由于我无法让Pavlo的答案在我的生产应用程序中工作,我已经在一个单独的测试应用程序中尝试过.该应用程序是一个WinForms应用程序,主要表单只包含一个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>
Run Code Online (Sandbox Code Playgroud)
如上所示,这会产生一个InvalidOperationException声明"只能基于具有基本类型'IFrameworkInputElement'的目标类型的样式."
这可以通过将固定TargetType="Hyperlink"在Style里面立即定义UserControl.Resources元素.但是,在显示消息时,它们的链接部分仍然具有默认的蓝色超链接样式:

简而言之,它不起作用,所以我欢迎任何其他建议/更正.:(
更新2:
得益于Pavlo的替代解决方案,它现在正在运行.:)
经过一些谷歌搜索后,我遇到了这篇文章:http://www.11011.net/archives/000692.html.
正如它在那里描述的那样,事实证明,不是从Control(和TextBlock和Hyperlink)派生的元素不会在DataTemplate边界之外寻找隐式样式.
同样,正如文章所说,可能的解决方法是明确指定样式键.在你的情况下,它可能是这样的:
<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 Errors}"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
然后,您可以添加一个隐式样式Hyperlink,只是在DataTemplate资源中引用我们的命名样式:
<DataTemplate DataType="{x:Type Importer:ConversionDetailsMessage}">
<DataTemplate.Resources>
<Style TargetType="{x:Type Hyperlink}"
BasedOn="{StaticResource MyDefaultHyperlinkStyle}"/>
</DataTemplate.Resources>
<TextBlock>
<Run Text="{Binding Message, Mode=OneTime}"/>
<Hyperlink Command="Common:ImportDataCommands.ExplainConversionMessage" CommandParameter="{Binding}">
<Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
并且因为数据模板可以在不同的地方使用,所以父容器可能没有定义具有键"MyDefaultHyperlinkStyle"的样式.在这种情况下,将抛出异常,说无法找到资源"MyDefaultHyperlinkStyle".要解决此问题,您可以使用此类键定义样式,该样式仅在App.xaml中的某处继承默认样式:
<Style x:Key="MyDefaultHyperlinkStyle"
BasedOn="{StaticResource {x:Type Hyperlink}}/>
Run Code Online (Sandbox Code Playgroud)
更新:
由于静态资源的性质,您在更新中包含的代码将无法工作,这意味着日期模板中的以下资源引用...
BasedOn="{StaticResource MyDefaultHyperlinkStyle}"
Run Code Online (Sandbox Code Playgroud)
...将始终指向以下资源(这是默认样式):
<Style x:Key="MyDefaultHyperlinkStyle" BasedOn="{StaticResource {x:Type Hyperlink}}"/>
Run Code Online (Sandbox Code Playgroud)
静态资源引用在编译时解析,因此使用树中最近的资源.
您可能很想使用DynamicResource,但不幸的是,该BasedOn属性不支持.
但是,Foreground属性支持动态资源,因此我们可以在我们的样式中使用相同的技巧.以下是修改为使用动态画笔的测试用户控件:
<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>
<SolidColorBrush x:Key="HyperlinkForeground"
Color="Blue" />
<SolidColorBrush x:Key="HyperlinkHoverForeground"
Color="Gray" />
<Style x:Key="MyDefaultHyperlinkStyle"
TargetType="Hyperlink"
BasedOn="{StaticResource {x:Type Hyperlink}}">
<Setter Property="Foreground"
Value="{DynamicResource HyperlinkForeground}" />
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground"
Value="{DynamicResource HyperlinkHoverForeground}" />
</Trigger>
</Style.Triggers>
</Style>
<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>
<SolidColorBrush x:Key="HyperlinkForeground"
Color="Yellow" />
<SolidColorBrush x:Key="HyperlinkHoverForeground"
Color="White" />
</StackPanel.Resources>
<TextBlock>Data import errors</TextBlock>
<ItemsControl ItemsSource="{Binding Messages}" />
</StackPanel>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
它按预期工作,即内部的所有链接StackPanel都是黄色/白色,而外面的链接是蓝色.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |