538 Stimmen

Was ist der Unterschied zwischen StaticResource und DynamicResource in WPF?

Wenn Ressourcen wie Pinsel, Vorlagen und Stile in WPF verwendet werden, können sie entweder als StaticResources angegeben werden

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

oder als DynamicResource

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

Meistens (immer?) funktioniert nur eine und die andere löst während der Laufzeit eine Ausnahme aus. Aber ich würde gerne wissen, warum:

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

I annehmen die Wahl zwischen statisch und dynamisch ist nicht so willkürlich, wie es scheint... aber ich kann das Muster nicht erkennen.

33 Stimmen

Es ist wichtig zu beachten, dass Windows 8 App-Entwickler keine DyanmicResource als Option haben, nur StaticResource.

2 Stimmen

@Jerry Nixon Gott sei Dank, ich habe nicht mehr gezählt, wie oft ich etwas nicht zum Laufen gebracht habe, weil ich DynamicResource statt StaticResource oder umgekehrt verwendet habe. Aus der Sicht des Programmierers ist das eine unnötige Komplexität. Eine Analogie dazu ist die Definition von Variablen. Sollte ich explizit angeben müssen, ob sie auf dem Heap oder dem Stack liegen? Und wenn ich das falsch mache, kommt es zu einem katastrophalen Laufzeitfehler?

0 Stimmen

Eine genauere Erläuterung von StaticResource und DynamicResource und wann sie zu verwenden sind, finden Sie unter msdn.microsoft.com/de-us/library/ms750613%28v=vs.100%29.aspx .

530voto

Phil Wright Punkte 22034

A StaticResource wird aufgelöst und der Eigenschaft während des Ladens der XAML zugewiesen, was geschieht, bevor die Anwendung tatsächlich ausgeführt wird. Sie wird nur einmal zugewiesen und alle Änderungen am Ressourcenwörterbuch werden ignoriert.

A DynamicResource weist der Eigenschaft beim Laden ein Expression-Objekt zu, sucht aber erst zur Laufzeit nach der Ressource, wenn das Expression-Objekt nach dem Wert gefragt wird. Dadurch wird die Suche nach der Ressource aufgeschoben, bis sie zur Laufzeit benötigt wird. Ein gutes Beispiel wäre ein Vorwärtsverweis auf eine später in der XAML definierte Ressource. Ein weiteres Beispiel ist eine Ressource, die bis zur Laufzeit gar nicht existiert. Sie wird das Ziel aktualisieren, wenn das Quellressourcenverzeichnis geändert wird.

4 Stimmen

Was muss sich ändern, bevor ich DynamicResource verwenden muss? Nehmen wir zum Beispiel eine Vorlage: Ich definiere sie einmal, aber dann können natürlich Auslöser und andere Dinge den Inhalt der Vorlage ändern, aber die Vorlage ist immer noch dieselbe. Würde StaticResource hier ausreichen?

8 Stimmen

Verwenden Sie StaticResource, wenn die Ressource, an die Sie anhängen, in der XAML vor dem Verwendungszeitpunkt definiert ist und sich während der gesamten Lebensdauer der laufenden Anwendung nicht ändert. In diesem Fall erhalten Sie eine bessere Leistung mit StaticResource.

4 Stimmen

Ist die Zwei-Wege-Bindung auf beide anwendbar, und wenn ja, was wäre der Unterschied in diesem Fall?

139voto

Akshay J Punkte 5077

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 nirgends deklariert. zur Laufzeit wird das ResourceDictionary der Hierarchie überprüft, da ich es nicht definiert habe, wird wohl der Standard verwendet.

Wenn ich den nachstehenden Code zum Click-Ereignis der Schaltfläche hinzufüge, wird der Hintergrund entsprechend aktualisiert, da er DynamicResource verwendet.

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 zwar "bevor" sie verwendet werden.

Ich hoffe, ich konnte einige Unklarheiten beseitigen.

0 Stimmen

Das war das hilfreichste und einfachste Beispiel für mich, danke :)

39voto

Afshin Punkte 500

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

37voto

Jeson Martajaya Punkte 6621
  1. StaticResource verwendet erste Wert. DynamicResource verwendet zuletzt Wert.
  2. DynamicResource kann für verschachteltes Styling verwendet werden, StaticResource nicht.

Nehmen wir an, Sie haben dieses verschachtelte Style-Wörterbuch. LightGreen befindet sich auf der Root-Ebene, während Pink innerhalb eines Gitters 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 Blick:

<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 es im Stil gefunden hat. DynamicResource überschreibt die Schaltfläche LightGreen als Pink, wenn es das Raster rendert.

StaticResource StaticResource

DynamicResource DynamicResource

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

StaticResource löst einen Fehler aus, wenn der Stil auf Root-Ebene (LightGreen) entfernt wird.

0 Stimmen

Es ist immer noch verwirrend, wie LightGreen als erstes im Ressourcenverzeichnis gefunden wird, weil Pink zuerst deklariert wird (wie das weiter oben). Ich vermute, wenn die xaml für den Stil sucht es zuerst die "nicht verschachtelten" ein. Eine kurze Erklärung wäre allerdings hilfreich.

21voto

CharithJ Punkte 44196

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

Der Unterschied zwischen statischen und dynamischen Ressourcen besteht darin, dass sich das zugrunde liegende Objekt ändert. Wenn auf die in der Ressourcensammlung definierte Bürste im Code zugegriffen wurde und sie auf eine andere Objektinstanz gesetzt wurde, wird Rectangle diese Änderung nicht erkennen.

Statische Ressourcen werden einmal durch ein referenzierendes Element abgerufen und für die gesamte Lebensdauer der Ressourcen verwendet. Dynamische Ressourcen hingegen werden jedes Mal abgerufen, wenn sie verwendet werden.

Der Nachteil der dynamischen Ressourcen ist, dass sie die Leistung der Anwendung beeinträchtigen können.

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

Am besten ist es, statische Ressourcen zu verwenden, es sei denn, es gibt einen besonderen Grund, z. B. wenn Sie die Ressource im Code dahinter dynamisch ändern wollen. Ein weiteres Beispiel für einen Fall, in dem Sie dynamische Ressourcen verwenden möchten, ist die Verwendung von SystemBrushes, SystenFonts und Systemparametern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X