次の非常に単純な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>
ここでの動的リソース(より複雑な状況で実際に必要)の使用は機能しません。静的リソースを使用すると、TextBlockが目的の色になります。リソースをFixedPageのレベルに移動することもトリックを行います。ただし、最上位の要素に1つの汎用リソースディクショナリが必要です(ユーザーが色やフォントなどに対して実行可能な変更を行うことができるため)。リソースをアプリケーションレベルに配置することも機能します。しかし、それは正当な理由からの選択肢ではありません。
なぜこれが機能しないのか、誰にも手がかりがあります。TextBlock以降の論理ツリーと関係がありますか?
MSDNリソースの概要には、次のように記載されています。
ルックアッププロセスは、プロパティを設定する要素によって定義されたリソースディクショナリ内で要求されたキーをチェックします。
- 要素がStyleプロパティを定義している場合、Style内のResourcesディクショナリがチェックされます。
- 要素がTemplateプロパティを定義している場合、FrameworkTemplate内のResourcesディクショナリがチェックされます。
次に、ルックアッププロセスは、論理ツリーを上方向にトラバースして、親要素とそのリソースディクショナリに到達します。これは、ルート要素に到達するまで続きます。
また、MSDNの上記の説明に従って、ブラシとスタイルを(ダミー)スタイルのリソースに入れてみました。しかし、それもうまくいきませんでした。
これはそれほど複雑なことではないと本当に感じていますが、おそらく私は何かを監督しています。どんな助けでも大歓迎です。
編集
TextBlockに"tb"という名前を付けてから、tb.FindResource( "TestStyle")を使用すると、例外がスローされます。そのため、リソースが明らかに見つかりません。LogicalTreeHelper.GetParent(tb)をチェックアウトし、見つかった親に対してそれを繰り返すと、期待される結果が得られます:TextBlock> FixedPage> PageContent> FixedDocument .. ..
EDIT2
これは完璧に機能します。以前に予測された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>
EDIT3
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はnull)。XAMLマークアップで静的リソースを使用すると、すべてが正常に機能します。