.net - try - xaml run tag




Qual é a diferença entre StaticResource e DynamicResource no WPF? (6)

Ao usar recursos como pincéis, modelos e estilos no WPF, eles podem ser especificados como StaticResources

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

ou como um DynamicResource

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

Na maioria das vezes (sempre?), Apenas um funciona e o outro lançará exceção durante o tempo de execução. Mas eu gostaria de saber porque:

  • Qual é a principal diferença? Como memória ou implicações de desempenho
  • Existem regras no WPF como "os pincéis são sempre estáticos" e "os modelos são sempre dinâmicos" etc.?

Eu assumo que a escolha entre Estático vs Dinâmico não é tão arbitrária quanto parece ... mas eu não consigo ver o padrão.


  1. StaticResource usa o primeiro valor. DynamicResource usa o último valor.
  2. DynamicResource pode ser usado para estilos aninhados, StaticResource não pode.

Suponha que você tenha este dicionário de estilo aninhado. O LightGreen está no nível da raiz enquanto o Pink está aninhado dentro de um Grid.

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

Em 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 irá processar o botão como LightGreen, o primeiro valor encontrado no estilo. O DynamicResource substituirá o botão LightGreen como Rosa, ao renderizar a Grade.

StaticResource

DynamicResource

Tenha em mente que o VS Designer trata DynamicResource como StaticResource. Ele terá o primeiro valor. Nesse caso, o VS Designer renderizará o botão como LightGreen, embora na verdade acabe em rosa.

StaticResource lançará um erro quando o estilo de nível raiz (LightGreen) for removido.


Benefício importante dos recursos dinâmicos

Se a inicialização do aplicativo levar muito tempo, você deverá usar recursos dinâmicos, pois os recursos estáticos sempre são carregados quando a janela ou o aplicativo é criado, enquanto os recursos dinâmicos são carregados quando são usados ​​pela primeira vez.

No entanto, você não verá nenhum benefício a menos que seu recurso seja extremamente grande e complexo.


Eu também estava confuso sobre eles. Veja este exemplo abaixo:

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

Aqui eu usei o recurso dinâmico para botão e janela e não o declarei em lugar. Em tempo de execução, o ResourceDictionary da hierarquia será verificado. Como não o defini, acho que o padrão será usado.

Se eu adicionar o código abaixo para clicar em evento de Button, já que eles usam DynamicResource, o plano de fundo será atualizado de acordo.

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

Se eles tivessem usado StaticResource:

  • O recurso deve ser declarado em XAML
  • E isso também "antes" eles são usados.

Espero que eu tenha esclarecido alguma confusão.


Os recursos lógicos permitem que você defina objetos no XAML, que não fazem parte da árvore visual, mas podem ser usados ​​na interface do usuário. Um dos exemplos de um recurso lógico é o Brush, que é usado para fornecer um esquema de cores. Geralmente, esses objetos são definidos como recursos, que são usados ​​por vários elementos dos aplicativos.

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

Agora, o recurso declarado acima pode ser usado como um recurso estático ou dinâmico. Um ponto a ser lembrado é que, ao usar recursos estáticos, ele deve ser definido primeiro no código XAML, antes de poder ser referido. Recursos estáticos e dinâmicos podem ser usados ​​como:

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

ou:

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

A diferença entre StaticResource e DynamicResource reside em como os recursos são recuperados pelos elementos de referência. StaticResource são recuperados apenas uma vez pelo elemento de referência e usados ​​por toda a vida útil do recurso. Por outro lado, DynamicResource são adquiridos toda vez que o objeto referenciado é usado.

Colocando de maneira mais simples, se a propriedade de cor de RadialGradientBrush for alterada em código para Laranja e Rosa, ela refletirá nos elementos somente quando o recurso for usado como DynamicResource. Abaixo está o código para alterar o recurso no código:

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

O demérito do DynamicResource é que ele reduz o desempenho do aplicativo porque os recursos são recuperados toda vez que são usados. A melhor prática é usar o StaticResource até que haja um motivo específico para usar o DynamicResource.

Fonte:
WPF: StaticResource vs. DynamicResource


Um StaticResource será resolvido e atribuído à propriedade durante o carregamento do XAML, que ocorre antes da execução do aplicativo. Só será atribuído uma vez e quaisquer alterações ao dicionário de recursos serão ignoradas.

Um DynamicResource atribui um objeto Expression à propriedade durante o carregamento, mas na verdade não pesquisa o recurso até o tempo de execução, quando o objeto Expression é solicitado pelo valor. Isso adia procurar o recurso até que seja necessário em tempo de execução. Um bom exemplo seria uma referência direta a um recurso definido posteriormente no XAML. Outro exemplo é um recurso que nem existirá até o tempo de execução. Ele atualizará o destino se o dicionário de recursos de origem for alterado.


Qual é a principal diferença? Como memória ou implicações de desempenho

A diferença entre recursos estáticos e dinâmicos vem quando o objeto subjacente é alterado. Se o seu Brush definido na coleção Resources tiver sido acessado no código e definido para uma instância de objeto diferente, o Rectangle não detectará essa alteração.

Recursos estáticos recuperados uma vez por elemento de referência e usados ​​durante a vida útil dos recursos. Considerando que, DynamicResources recupera toda vez que eles são usados.

A desvantagem dos recursos dinâmicos é que eles tendem a diminuir o desempenho do aplicativo.

Existem regras no WPF como "os pincéis são sempre estáticos" e "os modelos são sempre dinâmicos" etc.?

A melhor prática é usar os recursos estáticos, a menos que haja um motivo específico, como se você quisesse alterar o recurso no código por trás dinamicamente. Outro exemplo de instância em que você gostaria de usar resoruces dinâmicos inclui quando você usa o SystemBrushes, SystenFonts e System Parameters.







resources