it-swarm.com.de

Was ist der Unterschied zwischen StaticResource und DynamicResource in WPF?

Wenn Sie in WPF Ressourcen wie Pinsel, Vorlagen und Stile verwenden, können Sie diese entweder als StaticResources angeben

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

oder als DynamicResource

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

Meistens (immer?) Funktioniert nur eines und das andere löst zur Laufzeit eine Ausnahme aus. Aber ich würde gerne wissen warum:

  • Was ist der Hauptunterschied. Wie das Gedächtnis oder die Auswirkungen auf die Leistung
  • Gibt es in WPF Regeln wie "Pinsel sind immer statisch" und "Vorlagen sind immer dynamisch" usw.?

Ich nehme an die Wahl zwischen statisch und dynamisch ist nicht so willkürlich, wie es scheint ... aber ich sehe das Muster nicht.

445
Isak Savo

Ein StaticResource wird aufgelöst und der Eigenschaft zugewiesen, während die XAML geladen wird, bevor die Anwendung tatsächlich ausgeführt wird. Es wird nur einmal vergeben und alle Änderungen am Ressourcenwörterbuch werden ignoriert.

A DynamicResource weist der Eigenschaft während des Ladens ein Expression-Objekt zu, durchsucht die Ressource jedoch erst zur Laufzeit, wenn das Expression-Objekt nach dem Wert gefragt wird. Dies verzögert das Nachschlagen der Ressource, bis sie zur Laufzeit benötigt wird. Ein gutes Beispiel wäre ein Forward-Verweis auf eine Ressource, die später in der XAML definiert wird. Ein weiteres Beispiel ist eine Ressource, die erst zur Laufzeit vorhanden sein wird. Das Ziel wird aktualisiert, wenn das Quellressourcenwörterbuch geändert wird.

441
Phil Wright

Ich war auch verwirrt über sie. Siehe dieses Beispiel unten:

<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>

Hier habe ich dynamische Ressourcen für Schaltflächen und Fenster verwendet und sie nirgendwo deklariert. Zur Laufzeit wird das ResourceDictionary der Hierarchie überprüft. Da ich es nicht definiert habe, wird vermutlich die Standardeinstellung verwendet.

Wenn ich den folgenden Code hinzufüge, um auf Ereignis von Button zu klicken, wird der Hintergrund entsprechend aktualisiert, da sie DynamicResource verwenden.

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

Wenn sie StaticResource verwendet hätten:

  • Die Ressource muss in XAML deklariert werden
  • Und das auch "bevor" sie benutzt werden.

Hoffe, ich habe ein wenig Verwirrung gestillt.

115
Akshay J

StaticResource wird bei der Objektkonstruktion aufgelöst.
DynamicResource wird jedes Mal ausgewertet und aufgelöst, wenn das Steuerelement die Ressource benötigt.

30
Afshin

Mit logischen Ressourcen können Sie Objekte in XAML definieren, die nicht Teil des visuellen Baums sind, aber in Ihrer Benutzeroberfläche verwendet werden können. Ein Beispiel für eine logische Ressource ist Brush, mit dem ein Farbschema erstellt wird. Im Allgemeinen werden diese Objekte als Ressourcen definiert, die von mehreren Elementen der Anwendungen verwendet werden.

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

Die oben angegebene Ressource kann jetzt entweder als statische oder als dynamische Ressource verwendet werden. Beachten Sie, dass bei Verwendung statischer Ressourcen diese zuerst im XAML-Code definiert werden sollten, bevor auf sie verwiesen werden kann. Statische und dynamische Ressourcen können verwendet werden als:

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

oder:

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

Der Unterschied zwischen StaticResource und DynamicResource besteht darin, wie die Ressourcen von den referenzierenden Elementen abgerufen werden. StaticResource werden vom referenzierenden Element nur einmal abgerufen und für die gesamte Lebensdauer der Ressource verwendet. Andererseits werden DynamicResource jedes Mal erfasst, wenn das referenzierte Objekt verwendet wird.

Einfacher ausgedrückt: Wenn die Farbeigenschaft von RadialGradientBrush im Code in Orange und Pink geändert wird, werden Elemente nur berücksichtigt, wenn die Ressource als DynamicResource verwendet wird. Unten finden Sie den Code zum Ändern der Ressource im Code:

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

Der Nachteil von DynamicResource besteht darin, dass die Anwendungsleistung verringert wird, da Ressourcen bei jeder Verwendung abgerufen werden. Die beste Vorgehensweise ist die Verwendung von StaticResource, bis ein bestimmter Grund für die Verwendung von DynamicResource vorliegt.

Quelle:
WPF: StaticResource vs. DynamicResource

28
  1. StaticResource verwendet first value. DynamicResource verwendet den Wert last.
  2. DynamicResource kann für verschachtelte Stile verwendet werden, StaticResource nicht.

Angenommen, Sie haben dieses verschachtelte Stilwörterbuch. LightGreen befindet sich auf der Stammebene, während Pink in einem Raster verschachtelt ist.

<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>

Im Hinblick auf:

<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 rendert die Schaltfläche als LightGreen, den ersten Wert, den sie im Stil gefunden hat. DynamicResource überschreibt die LightGreen-Schaltfläche so pink wie das Raster.

StaticResource StaticResource

DynamicResource DynamicResource

Beachten Sie, dass VS Designer DynamicResource als StaticResource behandelt. Es wird den ersten Wert bekommen. In diesem Fall rendert VS Designer die Schaltfläche als LightGreen, obwohl sie tatsächlich als Pink endet.

StaticResource löst einen Fehler aus, wenn der Stil der Stammebene (LightGreen) entfernt wird.

19
Jeson Martajaya

Was ist der Hauptunterschied. Wie Speicher oder Auswirkungen auf die Leistung

Der Unterschied zwischen statischen und dynamischen Ressourcen entsteht, wenn sich das zugrunde liegende Objekt ändert. Wenn auf Ihren in der Resources-Auflistung definierten Pinsel im Code zugegriffen und eine andere Objektinstanz festgelegt wurde, erkennt Rectangle diese Änderung nicht.

Statische Ressourcen, die einmal vom referenzierenden Element abgerufen und für die Lebensdauer der Ressourcen verwendet werden. Während DynamicResources jedes Mal abrufen, wenn sie verwendet werden.

Der Nachteil von dynamischen Ressourcen besteht darin, dass sie die Anwendungsleistung tendenziell verringern.

Gibt es in WPF Regeln wie "Pinsel sind immer statisch" und "Vorlagen sind immer dynamisch" usw.?

Es wird empfohlen, statische Ressourcen zu verwenden, es sei denn, es gibt einen bestimmten Grund, aus dem Sie die Ressource im Code dahinter dynamisch ändern möchten. Ein weiteres Beispiel für eine Instanz, in der Sie keine dynamischen Ressourcen verwenden möchten, ist die Verwendung von System-Binsen, SystenFonts und Systemparametern.

13
CharithJ

Fanden alle Antworten nützlich, wollten nur noch einen Anwendungsfall hinzufügen.

In einem zusammengesetzten WPF-Szenario kann Ihr Benutzersteuerelement Ressourcen verwenden, die in einem anderen übergeordneten Fenster/Steuerelement (das dieses Benutzersteuerelement hostet) definiert sind, indem es auf diese Ressource als DynamicResource verweist.

Wie von anderen erwähnt, wird Staticresource zur Kompilierungszeit nachgeschlagen. Benutzersteuerelemente können nicht auf Ressourcen verweisen, die in Hosting/übergeordnetes Steuerelement definiert sind. In diesem Fall kann jedoch DynamicResource verwendet werden.

7

Wichtiger Vorteil der dynamischen Ressourcen

wenn der Start der Anwendung sehr lange dauert, müssen Sie dynamische Ressourcen verwenden, da statische Ressourcen immer beim Erstellen des Fensters oder der Anwendung geladen werden, während dynamische Ressourcen beim ersten Gebrauch geladen werden.

Sie werden jedoch keinen Nutzen sehen, wenn Ihre Ressource nicht extrem groß und komplex ist.

3
zamoldar

Dynamische Ressourcen können nur verwendet werden, wenn sich die festgelegte Eigenschaft auf einem Objekt befindet, das von einem Abhängigkeitsobjekt abgeleitet oder einfrierbar ist, wobei statische Ressourcen überall verwendet werden können. Sie können das gesamte Steuerelement mit statischen Ressourcen abstrahieren.

Statische Ressourcen werden unter folgenden Umständen verwendet:

  1. Wenn sich die Reaktionsressource zur Laufzeit ändert, ist dies nicht erforderlich.
  2. Wenn Sie eine gute Leistung mit vielen Ressourcen benötigen.
  3. Beim Verweisen auf Ressourcen innerhalb desselben Wörterbuchs.

Dynamische Ressourcen:

  1. Der Wert der Eigenschaft oder des Stylesetter-Themas ist erst zur Laufzeit bekannt
    • Dazu gehören System-, Anwendungs- und themenbasierte Einstellungen
    • Dies schließt auch Vorverweise ein.
  2. Verweisen auf große Ressourcen, die möglicherweise nicht geladen werden, wenn Seite, Fenster und Benutzersteuerung geladen werden.
  3. Referenzieren von Designstilen in einem benutzerdefinierten Steuerelement.
1
iaminvinicble