具有以下非常简单的 xaml:
<DocumentViewer Name="dv">
<FixedDocument Name="fd" Loaded="fd_loaded">
<FixedDocument.Resources>
<Style x:Key="TestStyle">
<Style.Setters>
<Setter Property="TextBlock.Foreground" Value="BlueViolet"/>
</Style.Setters>
</Style>
<SolidColorBrush x:Key="foregroundBrush" Color="Orange"/>
</FixedDocument.Resources>
<PageContent Name="pc">
<FixedPage Name="fp" Width="800" Height="600" Name="fp">
<TextBlock Name="tb" Style="{DynamicResource TestStyle}">
Lorem ipsum
</TextBlock>
<TextBlock Foreground="{DynamicResource foregroundBrush}" Margin="20">
Lorem ipsum
</TextBlock>
</FixedPage>
</PageContent>
</FixedDocument>
</DocumentViewer>
在这里使用动态资源(我在更复杂的情况下实际上需要)不起作用。使用静态资源将 TextBlocks 着色为所需的颜色。将资源移动到 FixedPage 的级别也可以解决问题。但我想在顶级元素上有一个通用资源字典(因为用户可以对颜色、字体等进行运行时更改)。将资源放在应用程序级别也确实有效。但这不是一个很好的选择。
任何人都知道为什么这不起作用。它与 TextBlock 向上的逻辑树有关吗?
MSDN 资源概述指出:
查找过程在设置属性的元素定义的资源字典中检查请求的键。
- 如果元素定义了 Style 属性,则检查 Style 中的 Resources 字典。
- 如果元素定义了 Template 属性,则检查 FrameworkTemplate 中的 Resources 字典。
查找过程然后向上遍历逻辑树,到达父元素及其资源字典。这一直持续到到达根元素。
根据上述MSDN的解释,我还尝试将Brush和Style放入(虚拟)样式的资源中。但这也没有用。
真的有感觉,这不可能那么复杂,但很可能是我监督的东西。任何帮助表示赞赏。
编辑
将 TextBlock 命名为“tb”然后使用 tb.FindResource("TestStyle") 会引发异常。因此,显然无法找到该资源。如果我检查 LogicalTreeHelper.GetParent(tb) 并为找到的父母重复该操作,我会得到预期的结果: TextBlock > FixedPage > PageContent > FixedDocument ...
编辑2
这很完美。与之前预测的 XAML 有什么区别?
<Window x:Class="WpfDynamicStyles2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="resBrush" Color="Orange"></SolidColorBrush>
</Grid.Resources>
<StackPanel>
<Button>
<TextBlock Foreground="{DynamicResource resBrush}">Dummy text...</TextBlock>
</Button>
</StackPanel>
</Grid>
</Window>
编辑3
private void fd_Loaded(object sender, RoutedEventArgs e)
{
Object obj = pc.TryFindResource("foregroundBrush");
obj = fp.TryFindResource("foregroundBrush");
obj = tb.TryFindResource("foregroundBrush");
}
无法解析放置在文本框的 Foreground 属性上的动态资源(实际资源位于 FixedDocument.Resources 级别)。同样在代码后面使用 TryFindResource 来自 pc (PageContent) 但来自 fp (FixedPage) 和 tb (TextBlock) 它无法解析资源(obj 为空)。在 XAML 标记中使用静态资源时,一切正常。