Domanda

Quando si utilizzano risorse come pennelli, modelli e stili in WPF, possono essere specificati come StaticResources

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

o come DynamicResource

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

Il più delle volte (sempre?), solo uno funziona e l'altro genererà eccezioni durante il runtime. Ma vorrei sapere perché:

  • Qual è la differenza principale. Come le implicazioni di memoria o prestazioni
  • Ci sono regole in WPF come i pennelli " sono sempre statici " e "i modelli sono sempre dinamici" ecc.?

I presumo la scelta tra Statico vs Dinamico non è così arbitraria come sembra ... ma non riesco a vedere lo schema.

È stato utile?

Soluzione

Una StaticResource sarà risolta e assegnato alla proprietà durante il caricamento di XAML che si verifica prima che l'applicazione venga effettivamente eseguita. Sarà assegnato una sola volta e qualsiasi modifica al dizionario delle risorse verrà ignorata.

A DynamicResource assegna un oggetto Expression sulla proprietà durante il caricamento, ma in realtà non cerca la risorsa fino al runtime quando viene richiesto il valore dell'oggetto Expression. Ciò impedisce di cercare la risorsa fino a quando non è necessaria in fase di esecuzione. Un buon esempio potrebbe essere un riferimento diretto a una risorsa definita più avanti in XAML. Un altro esempio è una risorsa che non esisterà nemmeno fino al runtime. Aggiornerà la destinazione se il dizionario delle risorse di origine viene modificato.

Altri suggerimenti

Ero anche confuso su di loro. Vedi questo esempio di seguito:

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

Qui ho usato la risorsa dinamica per pulsante e finestra e non l'ho dichiarata da nessuna parte. In fase di runtime, verrà verificato il ResourceDictionary della gerarchia. Poiché non l'ho definito, suppongo che verrà utilizzato il valore predefinito.

Se aggiungo il codice qui sotto per fare clic sull'evento di Button, poiché usano DynamicResource, lo sfondo verrà aggiornato di conseguenza.

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

Se avessero usato StaticResource:

  • La risorsa deve essere dichiarata in XAML
  • E anche quello " prima di " sono usati.

Spero di aver chiarito un po 'di confusione.

StaticResource sarà risolto sulla costruzione di oggetti.
DynamicResource verrà valutato e risolto ogni volta che il controllo necessita della risorsa.

Le risorse logiche consentono di definire oggetti in XAML, che non fanno parte dell'albero visivo ma possono essere utilizzati nell'interfaccia utente. Uno degli esempi di una risorsa logica è Pennello, che viene utilizzato per fornire una combinazione di colori. Generalmente tali oggetti sono definiti come risorse, che vengono utilizzati da più elementi delle applicazioni.

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

Ora, la risorsa sopra dichiarata può essere utilizzata come risorsa statica o dinamica. Un punto da ricordare è che, quando si utilizzano risorse statiche, dovrebbe essere definito per la prima volta nel codice XAML, prima di poterlo fare riferimento. Le risorse statiche e dinamiche possono essere utilizzate come:

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

o

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

La differenza tra StaticResource e DynamicResource risiede nel modo in cui le risorse vengono recuperate dagli elementi di riferimento. StaticResource viene recuperato una sola volta dall'elemento di riferimento e utilizzato per l'intera vita della risorsa. D'altra parte, DynamicResource viene acquisito ogni volta che viene utilizzato l'oggetto di riferimento.

In parole povere, se la proprietà color di RadialGradientBrush viene modificata nel codice in Arancione e Rosa, si rifletterà sugli elementi solo quando la risorsa viene utilizzata come DynamicResource. Di seguito è riportato il codice per modificare la risorsa nel codice:

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

Il demerito di DynamicResource è che riduce le prestazioni dell'applicazione perché le risorse vengono recuperate ogni volta che vengono utilizzate. La migliore pratica è quella di utilizzare StaticResource fino a quando non vi è un motivo specifico per utilizzare DynamicResource.

Fonte:
WPF: StaticResource vs. DynamicResource

  1. StaticResource utilizza il primo valore. DynamicResource utilizza ultimo valore.
  2. DynamicResource può essere utilizzato per lo stile nidificato, mentre StaticResource no.

Supponi di avere questo dizionario di stile nidificato. LightGreen si trova al livello principale mentre Pink è nidificato all'interno di una griglia.

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

In vista:

<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 renderà il pulsante come LightGreen, il primo valore trovato nello stile. DynamicResource sovrascriverà il pulsante LightGreen su Pink mentre visualizza la griglia.

StaticResource StaticResource

DynamicResource DynamicResource

Tieni presente che VS Designer tratta DynamicResource come StaticResource. Otterrà il primo valore. In questo caso, VS Designer renderà il pulsante come LightGreen anche se in realtà diventa Pink.

StaticResource genererà un errore quando viene rimosso lo stile di livello radice (LightGreen).

Qual è la differenza principale. Come le implicazioni di memoria o prestazioni

La differenza tra risorse statiche e dinamiche viene quando cambia l'oggetto sottostante. Se il tuo pennello definito nella raccolta Risorse era accessibile nel codice e impostato su un'istanza di oggetto diversa, Rectangle non rileverà questa modifica.

Risorse statiche recuperate una volta facendo riferimento all'elemento e utilizzate per la durata delle risorse. Considerando che DynamicResources recupera ogni volta che vengono utilizzati.

L'aspetto negativo delle risorse dinamiche è che tendono a ridurre le prestazioni delle applicazioni.

Ci sono regole in WPF come i pennelli " sono sempre statici " e "i modelli sono sempre dinamici" ecc.?

La migliore pratica è quella di utilizzare le risorse statiche a meno che non vi sia un motivo specifico come se si desidera modificare in modo dinamico la risorsa nel codice. Un altro esempio di esempio in cui si desidera utilizzare risorse dinamiche è quando si utilizzano SystemBrushes, SystenFonts e Parametri di sistema.

Trovate tutte le risposte utili, volevo solo aggiungere un altro caso d'uso.

In uno scenario composito WPF, il controllo utente può utilizzare le risorse definite in qualsiasi altra finestra / controllo parent (che ospiterà questo controllo utente) facendo riferimento a tale risorsa come DynamicResource.

Come menzionato da altri, Staticresource verrà consultato al momento della compilazione. I controlli utente non possono fare riferimento a quelle risorse definite nel controllo di hosting / padre. Tuttavia, DynamicResource potrebbe essere utilizzato in questo caso.

Importante vantaggio delle risorse dinamiche

se l'avvio dell'applicazione richiede tempi estremamente lunghi, è necessario utilizzare risorse dinamiche, perché le risorse statiche vengono sempre caricate quando viene creata la finestra o l'app, mentre le risorse dinamiche vengono caricati al primo utilizzo.

Tuttavia, non vedrai alcun vantaggio a meno che la tua risorsa non sia estremamente grande e complesso.

Le risorse dinamiche possono essere utilizzate solo quando la proprietà impostata è sull'oggetto derivato dall'oggetto dipendenza o congelabile dove le risorse statiche possono essere utilizzate ovunque. Puoi sottrarre l'intero controllo usando risorse statiche.

Le risorse statiche vengono utilizzate nelle seguenti circostanze:

  1. Quando non è richiesta la modifica delle risorse di reazione in fase di esecuzione.
  2. Se hai bisogno di una buona prestazione con molte risorse.
  3. Mentre si fa riferimento a risorse all'interno dello stesso dizionario.

Risorse dinamiche:

  1. Il valore del tema del setter di proprietà o stile non è noto fino al runtime
    • Include sistema, applicazione, impostazioni basate sul tema
    • Questo include anche riferimenti diretti.
  2. Riferimenti a risorse di grandi dimensioni che potrebbero non essere caricate durante il caricamento di pagine, finestre, controlli utente.
  3. Riferimenti agli stili di tema in un controllo personalizzato.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top