После некоторого поиска в Google я наткнулся на этот пост: 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>
Затем вы можете добавить неявный стиль для 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>
И поскольку шаблон данных можно использовать в разных местах, существует вероятность того, что родительский контейнер не определяет стиль с ключом «MyDefaultHyperlinkStyle».В этом случае будет сгенерировано исключение о том, что ресурс "MyDefaultHyperlinkStyle" не найден.Чтобы решить эту проблему, вы можете определить стиль с таким ключом, который будет наследовать стиль по умолчанию только где-то в App.xaml:
<Style x:Key="MyDefaultHyperlinkStyle"
BasedOn="{StaticResource {x:Type Hyperlink}}/>
Обновление:
Код, который вывключение в ваше обновление не будет работать из-за природы статических ресурсов, что означает, что следующая ссылка на ресурс в шаблоне даты ...
BasedOn="{StaticResource MyDefaultHyperlinkStyle}"
... всегда будет указывать на следующий ресурс (которыйстиль по умолчанию):
<Style x:Key="MyDefaultHyperlinkStyle" BasedOn="{StaticResource {x:Type Hyperlink}}"/>
Статические ссылки на ресурсы разрешаются во время компиляции, поэтому используется ближайший ресурс в дереве.
Возможно, вы захотите использовать 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>
Он работает как положено, то есть все ссылки внутри StackPanel
будут желтыми / белыми, а снаружи они будут синими.
Надеюсь, это поможет.