Question

Lorsque vous utilisez des ressources telles que des pinceaux, des modèles et des styles dans WPF, vous pouvez les spécifier en tant que ressources statiques

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

ou en tant que DynamicResource

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

La plupart du temps (toujours?), un seul fonctionne et l'autre lève une exception lors de l'exécution. Mais j'aimerais savoir pourquoi:

  • Quelle est la différence principale? Comme les implications de mémoire ou de performance
  • Existe-t-il des règles dans WPF telles que "les balais sont toujours statiques" et "les modèles sont toujours dynamiques". etc.?

Je suppose que le choix entre statique et dynamique n'est pas aussi arbitraire qu'il y paraît ... mais je ne parviens pas à voir le schéma.

Était-ce utile?

La solution

Un StaticResource sera résolu. et assigné à la propriété pendant le chargement du XAML qui se produit avant que l'application soit réellement exécutée. Il ne sera attribué qu'une seule fois et toutes les modifications apportées au dictionnaire de ressources seront ignorées.

Une attribution de ressources dynamiques un objet Expression associé à la propriété pendant le chargement, mais ne recherche pas la ressource avant l'exécution, lorsque l'objet Expression est invité à indiquer la valeur. Cela retarde la recherche de la ressource jusqu'à ce qu'elle soit nécessaire au moment de l'exécution. Un bon exemple serait une référence directe à une ressource définie ultérieurement dans le code XAML. Un autre exemple est une ressource qui n'existera même pas avant l'exécution. Il mettra à jour la cible si le dictionnaire de ressources source est modifié.

Autres conseils

J'étais aussi confus à leur sujet. Voir cet exemple ci-dessous:

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

Ici, j'ai utilisé une ressource dynamique pour le bouton et la fenêtre et je ne l'ai déclarée nulle part. Au moment de l'exécution, le ResourceDictionary de la hiérarchie sera vérifié.Etant donné que je ne l'ai pas définie, je suppose que la valeur par défaut sera utilisée.

Si j'ajoute le code ci-dessous pour cliquer sur l'événement de Button, étant donné qu'ils utilisent DynamicResource, l'arrière-plan sera mis à jour en conséquence.

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

S'ils avaient utilisé StaticResource:

  • La ressource doit être déclarée en XAML
  • Et cela aussi "avant" ils sont utilisés.

J'espère que j'ai effacé une certaine confusion.

StaticResource sera résolu lors de la construction de l'objet.
DynamicResource sera évalué et résolu chaque fois que le contrôle a besoin de la ressource.

Les ressources logiques vous permettent de définir des objets en XAML, qui ne font pas partie de l'arborescence visuelle mais peuvent être utilisés dans votre interface utilisateur. Un des exemples de ressource logique est Pinceau, utilisé pour fournir un jeu de couleurs. Généralement, ces objets sont définis en tant que ressources, utilisées par plusieurs éléments des applications.

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

Maintenant, la ressource déclarée ci-dessus peut être utilisée en tant que ressource statique ou dynamique. Un point à retenir est que, lors de l’utilisation de ressources statiques, il faut d’abord le définir en code XAML avant de pouvoir le renvoyer. Les ressources statiques et dynamiques peuvent être utilisées comme:

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

ou:

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

La différence entre StaticResource et DynamicResource réside dans la façon dont les ressources sont récupérées par les éléments de référence. StaticResource ne sont extraits qu'une seule fois par l'élément de référencement et sont utilisés pendant toute la durée de vie de la ressource. D'autre part, DynamicResource est acquis chaque fois que l'objet référencé est utilisé.

En termes plus simples, si la propriété color de RadialGradientBrush est modifiée en code en orange et rose, elle ne reflétera les éléments que lorsque la ressource est utilisée en tant que DynamicResource. Voici le code pour changer la ressource dans le code:

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

Le démon de DynamicResource est qu’il réduit les performances de l’application car les ressources sont récupérées à chaque utilisation. La meilleure pratique consiste à utiliser StaticResource jusqu’à ce qu’il y ait une raison spécifique d’utiliser DynamicResource.

Source:
WPF: StaticResource ou DynamicResource

  1. StaticResource utilise la première valeur. DynamicResource utilise la dernière valeur.
  2. DynamicResource peut être utilisé pour le style imbriqué, pas StaticResource.

Supposons que vous ayez ce dictionnaire de styles imbriqué. LightGreen est au niveau racine tandis que Pink est imbriqué dans une grille.

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

En vue:

<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 affichera le bouton sous la forme LightGreen, la première valeur trouvée dans le style. DynamicResource remplacera le bouton LightGreen en rose au rendu de la grille.

StaticResource StaticResource

DynamicResource DynamicResource

N'oubliez pas que VS Designer traite DynamicResource en tant que StaticResource. Il aura la première valeur. Dans ce cas, VS Designer rendra le bouton au format LightGreen, même s’il apparaît en rose.

StaticResource émettra une erreur lorsque le style de niveau racine (LightGreen) sera supprimé.

Quelle est la différence principale. Comme pour la mémoire ou les conséquences sur les performances

La différence entre les ressources statiques et dynamiques survient lorsque l'objet sous-jacent change. Si votre pinceau défini dans la collection Resources a été accédé en code et défini sur une instance d'objet différente, Rectangle ne détectera pas cette modification.

Ressources statiques récupérées une fois par élément de référence et utilisées pour la durée de vie des ressources. Considérant que, DynamicResources récupère chaque fois qu'ils sont utilisés.

L'inconvénient des ressources dynamiques est qu'elles tendent à réduire les performances des applications.

Existe-t-il des règles dans WPF telles que "les balais sont toujours statiques" " et "les modèles sont toujours dynamiques". etc.?

La meilleure pratique consiste à utiliser des ressources statiques, sauf en cas de raison particulière, par exemple si vous souhaitez modifier les ressources dans le code de manière dynamique. Un autre exemple de cas dans lequel vous voudriez utiliser des ressources dynamiques incluent lorsque vous utilisez SystemBrushes, SystenFonts et les paramètres système.

Toutes les réponses ont été utiles, je voulais juste ajouter un cas d'utilisation supplémentaire.

Dans un scénario WPF composite, votre contrôle utilisateur peut utiliser les ressources définies dans tout autre contrôle / fenêtre parent (destiné à héberger ce contrôle utilisateur) en faisant référence à cette ressource en tant que DynamicResource.

Comme mentionné par d’autres, Staticresource sera consulté au moment de la compilation. Les contrôles utilisateur ne peuvent pas faire référence aux ressources définies dans le contrôle hôte / parent. Toutefois, DynamicResource peut être utilisé dans ce cas.

Avantage important des ressources dynamiques

si le démarrage de l'application prend énormément de temps, vous devez utiliser des ressources dynamiques, parce que les ressources statiques sont toujours chargées lors de la création de la fenêtre ou de l'application, alors que les ressources dynamiques sont chargés lors de leur première utilisation.

Toutefois, vous ne verrez aucun avantage si votre ressource est extrêmement volumineuse et complexe.

Les ressources dynamiques ne peuvent être utilisées que lorsque la propriété définie est définie sur un objet dérivé d'un objet de dépendance ou gelable, les ressources statiques pouvant être utilisées n'importe où. Vous pouvez faire abstraction de tout contrôle en utilisant des ressources statiques.

Les ressources statiques sont utilisées dans les cas suivants:

  1. Il n'est pas nécessaire de modifier la ressource de réaction au moment de l'exécution.
  2. Si vous avez besoin d'une bonne performance avec beaucoup de ressources.
  3. Tout en référençant des ressources dans le même dictionnaire.

Ressources dynamiques:

  1. La valeur du thème de la propriété ou du créateur de style n'est pas connue avant l'exécution
    • Ceci inclut le système, les applications, les paramètres basés sur les thèmes
    • Ceci inclut également les références en aval.
  2. Référencer des ressources volumineuses qui risquent de ne pas se charger lorsque la page, les fenêtres et les contrôles utilisateur se chargent.
  3. Référencement des styles de thème dans un contrôle personnalisé.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top