WPFにあってSilverlight 2 Betaにないシリーズ「DynamicResource」

このシリーズが続くのかどうかも定かではありませんが、WPFにはあるけれどもSilverlight 2 Betaにはないという部分を紹介していこうと思います。


まずは簡単なところからということで、DynamicResourceです。ご存知の方も多いかと思いますが、WPFにあるStaticResouceとDynamicResourceという2つのリソース参照のうち、Silverlight 2 BetaではStaticResouceのみが利用可能です。これによりどんなことができなくなっているかは、2つのリソース参照の違いを理解すれば分かります。


XAMLWPF

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Window1" x:Name="Window" Title="Window1"
    Width="300" Height="300">
    <Window.Resources>
        <SolidColorBrush x:Key="MyFillBrush" Color="Red"/>
    </Window.Resources>
 
    <StackPanel x:Name="LayoutRoot">
        <Rectangle Fill="{DynamicResource MyFillBrush}" Height="100" Margin="5"/>
        <Rectangle Fill="{StaticResource MyFillBrush}" Height="100" Margin="5"/>
        <Button Content="リソースの変更" x:Name="button" Click="button_Click"/>
    </StackPanel>
</Window>


Visual BasicWPF
Private Sub button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Me.Resources.Clear()
    Dim newResource As New SolidColorBrush(Colors.Blue)
    Me.Resources.Add("MyFillBrush", newResource)
End Sub


上記のコードの実行結果は下記のようになります。



結果を見ますと、StaticeResourceを使ったほうは色が変化しないのに対して、DynamicResouceを使ったほうは色が青色に変化しています。


この結果から、リソースの内容を動的に変更した場合にStaticeResourceの場合にはそれが反映されないと理解しがちですが、そうではありません。
ボタンのClickイベントのコードを下記の様に変更すると、StaticResorceでも色は変更されます。
Visual BasicWPF
Private Sub button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    CType(Me.FindResource("MyFillBrush"), SolidColorBrush).Color = Colors.Blue
End Sub


StaticResourceは、リソースキーの検索が読み込み時の一回しか行われないリソース参照です。それに対してDynamicResourceはリソースキーの検索が実行時に都度行われます。


つまり、DynamiceResourceでなければならいないというケースは、システムのテーマといったアプリケーションの外部でリソースが変更されるようなものに限られます。アプリケーション内でリソースの値を変更する場合にはStaticeResourceでも問題ありません。


ただし、StaticeResourceには読み込み時にリソースキーの検索が行われるという性質上、使用するリソースは参照する場所よりも前に定義されている必要があることだけは注意が必要です。