it-swarm-ja.com

WPFのStaticResourceとDynamicResourceの違いは何ですか?

WPFでブラシ、テンプレート、スタイルなどのリソースを使用する場合、それらはStaticResourcesとして指定できます。

<Rectangle Fill="{StaticResource MyBrush}" />

またはDynamicResourceとして

<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}"  />

ほとんどの場合(常に?)、一方のみが動作し、もう一方は実行時に例外をスローします。しかし、私はその理由を知りたいのですが。

  • 主な違いは何ですか。メモリまたはパフォーマンスへの影響
  • 「ブラシは常に静的」や「テンプレートは常に動的」などのWPFのルールはありますか?

I 仮定静的か動的かの選択は、見かけほど恣意的ではありません...しかし、パターンが見えません。

440
Isak Savo

アプリケーションが実際に実行される前に発生するXAMLのロード中に、 StaticResource が解決され、プロパティに割り当てられます。一度だけ割り当てられ、リソースディクショナリへの変更は無視されます。

A DynamicResource はロード中にExpressionオブジェクトをプロパティに割り当てますが、Expressionオブジェクトが値を要求される実行時まで実際にはリソースをルックアップしません。これは実行時に必要になるまでリソースの検索を遅らせます。良い例は、XAMLの後半で定義されているリソースへの前方参照です。もう1つの例は、実行時まで存在しないリソースです。ソースリソースディクショナリが変更されると、ターゲットが更新されます。

434
Phil Wright

私もそれらについて混乱していました。以下の例を見てください。

<Window x:Class="WpfApplicationWPF.CommandsWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        Title="CommandsWindow" Height="300" Width="300">

    <StackPanel>
        <Button Name="ButtonNew" 
                Click="ButtonNew_Click" 
                Background="{DynamicResource PinkBrush}">NEW</Button>
        <Image Name="ImageNew" 
               Source="pack://application:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

ここではボタンとウィンドウに動的リソースを使用し、どこにも宣言していません。実行時に、階層のResourceDictionaryがチェックされます。定義していないので、デフォルトが使用されると思います。

Buttonのclickイベントに以下のコードを追加すると、DynamicResourceを使用するため、それに応じて背景が更新されます。

private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
    this.Resources.Add(  "PinkBrush"
                         ,new SolidColorBrush(SystemColors.DesktopColor)
                       );
}

彼らがStaticResourceを使ったことがあるならば:

  • リソースはXAMLで宣言する必要があります
  • そしてそれもまた「前に」使われるのです。

私が混乱を一掃したことを願っています。

113
Akshay J

StaticResourceはオブジェクト構築時に解決されます。
コントロールがリソースを必要とするたびに、DynamicResourceは評価され解決されます。

30
Afshin

論理リソースを使用すると、XAMLでオブジェクトを定義できます。これはビジュアルツリーの一部ではありませんが、ユーザーインターフェイスで使用できます。論理リソースの例の1つは、カラースキームを提供するために使用されるBrushです。一般にこれらのオブジェクトはリソースとして定義され、アプリケーションの複数の要素によって使用されます。

<Window.Resources>
    <RadialGradientBrush x:Key="myGradientBrush">
        <GradientStop Color="Green" Offset="0"/>
        <GradientStop Color="Blue" Offset="2"/>
    </RadialGradientBrush>
</Window.Resources>

現在、上記の宣言されたリソースは、静的リソースまたは動的リソースとして使用できます。覚えておくべき1つの点は、静的リソースを使用するときは、XAMLコードで参照する前に、最初に定義する必要があるということです。静的リソースと動的リソースは次のように使用できます。

<Grid Background="{StaticResource myGradientBrush}"></Grid>

または

<Grid Background="{DynamicResource myGradientBrush}"></Grid>

StaticResourceとDynamicResourceの違いは、参照元要素によるリソースの取得方法にあります。 StaticResourceは参照元要素によって一度だけ取得され、リソースの有効期間全体にわたって使用されます。一方、DynamicResourceは参照されるオブジェクトが使用されるたびに取得されます。

簡単に言えば、RadialGradientBrushのcolorプロパティがコード内でOrangeとPinkに変更された場合、resourceがDynamicResourceとして使用されている場合にのみ要素に反映されます。以下は、コード内のリソースを変更するためのコードです。

RadialGradientBrush radialGradientBrush =
    new RadialGradientBrush(Colors.Orange, Colors.Pink);
this.Resources["myGradientBrush"] = radialGradientBrush;

DynamicResourceの短所は、リソースが使用されるたびに取得されるため、アプリケーションのパフォーマンスが低下することです。ベストプラクティスは、DynamicResourceを使用する特定の理由があるまでStaticResourceを使用することです。

ソース:
WPF:StaticResource vs. DynamicResource

27
  1. StaticResourceは最初のの値を使います。 DynamicResourceはlast valueを使用します。
  2. DynamicResourceはネストされたスタイルに使用できますが、StaticResourceは使用できません。

このネストされたStyle辞書があるとします。ピンクはグリッド内にネストされていますが、LightGreenはルートレベルです。

<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
                <Setter Property="Background" Value="Pink"/>
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
        <Setter Property="Background" Value="LightGreen"/>
    </Style>
</ResourceDictionary>

ビューで:

<Window x:Class="WpfStyleDemo.ConflictingStyleWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        Title="ConflictingStyleWindow" Height="100" Width="100">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ConflictingStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Style="{DynamicResource ConflictButton}" Content="Test"/>
    </Grid>
</Window>

StaticResourceは、ボタンをスタイルで最初に見つかったLightGreenとしてレンダリングします。 DynamicResourceは、グリッドを描画するときにLightGreenボタンをピンクとして上書きします。

StaticResource StaticResource

DynamicResource DynamicResource

VS DesignerはDynamicResourceをStaticResourceとして扱うことに注意してください。最初の値になります。この場合、VS DesignerはボタンをLightGreenとしてレンダリングしますが、実際はピンクになります。

ルートレベルのスタイル(LightGreen)が削除されると、StaticResourceはエラーをスローします。

19
Jeson Martajaya

主な違いは何ですか。メモリやパフォーマンスへの影響など

静的リソースと動的リソースの違いは、基礎となるオブジェクトが変わるときに生じます。 Resourcesコレクションで定義されているBrushがコードでアクセスされ、別のオブジェクトインスタンスに設定されている場合、Rectangleはこの変更を検出しません。

静的リソースは、要素を参照することによって一度取得され、リソースの存続期間の間使用されます。一方、DynamicResourceは使用されるたびに取得します。

動的リソースの欠点は、アプリケーションのパフォーマンスが低下する傾向があることです。

"ブラシは常に静的"、 "テンプレートは常に動的"などのようなWPFのルールはありますか?

最善の方法は、動的にビハインドコードのリソースを変更したいというような特別な理由がない限り、静的リソースを使用することです。動的リソースを使用したくないインスタンスのもう1つの例としては、SystemBrushes、SystenFonts、およびSystem Parametersを使用する場合があります。

13
CharithJ

すべての答えが役に立つとわかったので、もう1つユースケースを追加したいと思いました。

複合WPFシナリオでは、そのリソースをDynamicResourceとして参照することで、ユーザーコントロールは他の親ウィンドウ/コントロール(このユーザーコントロールをホストする)に定義されたリソースを利用できます。

他の人が述べたように、静的リソースはコンパイル時に調べられます。ユーザーコントロールは、ホスティング/親コントロールで定義されているリソースを参照できません。ただし、この場合はDynamicResourceを使用できます。

7

動的リソースの重要な利点

アプリケーションの起動に非常に時間がかかる場合は、動的リソースを使用する必要があります。静的リソースはウィンドウまたはアプリケーションの作成時に常にロードされ、動的リソースは最初の使用時にロードされるためです。

ただし、リソースが非常に大きく複雑でない限り、メリットはありません。

3
zamoldar

動的リソースは、設定されているプロパティが依存オブジェクトから派生したオブジェクトにある場合、または静的リソースがどこでも使用できる場合はフリーズ可能な場合にのみ使用できます。あなたは静的なリソースを使用して全体の制御を抽象化することができます

静的リソースは以下の状況で使用されます。

  1. 実行時に反応リソースを変更する必要がない場合.
  2. あなたがたくさんのリソースで良いパフォーマンスを必要とするなら。
  3. 同じ辞書内のリソースを参照している間。

動的リソース:

  1. プロパティやスタイルセッターのテーマの値は実行時までわからない
    • これにはシステム、アプリケーション、テーマベースの設定が含まれます
    • これには前方参照も含まれます。
  2. ページ、ウィンドウ、ユーザーコントロールが読み込まれるときに読み込まれない可能性がある大きなリソースを参照します。
  3. カスタムコントロールでテーマスタイルを参照する.
1
iaminvinicble