Pregunta

Cuando se utilizan recursos como pinceles, plantillas y estilos en WPF, se pueden especificar como StaticResources

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

o como DynamicResource

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

La mayoría de las veces (¿siempre?), solo una funciona y la otra arrojará una excepción durante el tiempo de ejecución. Pero me gustaría saber por qué:

  • ¿Cuál es la principal diferencia? Me gustan las implicaciones de memoria o rendimiento
  • ¿Hay reglas en WPF, ya que " los pinceles son siempre estáticos " y " las plantillas son siempre dinámicas " etc.?

Supongo que la elección entre Estático y Dinámico no es tan arbitraria como parece ... pero no veo el patrón.

¿Fue útil?

Solución

A StaticResource se resolverá y asignado a la propiedad durante la carga del XAML que se produce antes de que la aplicación se ejecute realmente. Solo se asignará una vez y se ignorarán todos los cambios al diccionario de recursos.

A DynamicResource asignados un objeto de Expresión a la propiedad durante la carga, pero en realidad no busca el recurso hasta el tiempo de ejecución cuando se le pide el valor al objeto de Expresión. Esto difiere en buscar el recurso hasta que sea necesario en el tiempo de ejecución. Un buen ejemplo sería una referencia a un recurso definido más adelante en el XAML. Otro ejemplo es un recurso que ni siquiera existirá hasta el tiempo de ejecución. Actualizará el objetivo si se cambia el diccionario de recursos de origen.

Otros consejos

También estaba confundido acerca de ellos. Vea este ejemplo a continuación:

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

Aquí he utilizado el recurso dinámico para el botón y la ventana y no lo he declarado en ninguna parte. Durante el tiempo de ejecución, se comprobará el ResourceDictionary de la jerarquía. Ya que no lo he definido, creo que se utilizará el valor predeterminado.

Si agrego el siguiente código para hacer clic en el evento de Button, ya que usan DynamicResource, el fondo se actualizará en consecuencia.

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

Si hubieran usado StaticResource:

  • El recurso debe ser declarado en XAML
  • Y eso también " antes " son usados.

Espero haber aclarado alguna confusión.

StaticResource se resolverá en la construcción del objeto.
DynamicResource se evaluará y resolverá cada vez que el control necesite el recurso.

Los recursos lógicos le permiten definir objetos en XAML, que no son parte del árbol visual, pero se pueden usar en su interfaz de usuario. Uno de los ejemplos de un recurso lógico es Brush, que se utiliza para proporcionar un esquema de color. En general, esos objetos se definen como recursos, que son utilizados por múltiples elementos de las aplicaciones.

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

Ahora, el recurso declarado arriba podría usarse como recurso estático o dinámico. Un punto a recordar es que, cuando se usan recursos estáticos, primero debe definirse en el código XAML, antes de poder remitirlo. Los recursos estáticos y dinámicos se pueden utilizar como:

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

o:

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

La diferencia entre StaticResource y DynamicResource reside en cómo los elementos de referencia recuperan los recursos. StaticResource se recupera una sola vez por el elemento de referencia y se utiliza durante toda la vida del recurso. Por otro lado, DynamicResource se adquiere cada vez que se utiliza el objeto referenciado.

Poniéndolo de una manera más simple, si la propiedad de color de RadialGradientBrush se cambia en código a Naranja y Rosa, entonces se reflejará en los elementos solo cuando el recurso se use como DynamicResource. A continuación se muestra el código para cambiar el recurso en el código:

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

La desventaja de DynamicResource es que reduce el rendimiento de la aplicación porque los recursos se recuperan cada vez que se usan. La mejor práctica es usar StaticResource hasta que haya una razón específica para usar DynamicResource.

Fuente:
WPF: StaticResource vs. DynamicResource

  1. StaticResource usa el valor primero . DynamicResource utiliza el valor último .
  2. DynamicResource puede usarse para estilos anidados, StaticResource no puede.

Supongamos que tienes este diccionario de estilo anidado. LightGreen se encuentra en el nivel raíz, mientras que Pink está anidado dentro de una cuadrícula.

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

A la 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 renderizará el botón como LightGreen, el primer valor que encontró en el estilo. DynamicResource anulará el botón LightGreen como rosa cuando muestre la cuadrícula.

StaticResource StaticResource

DynamicResource DynamicResource

Tenga en cuenta que VS Designer trata a DynamicResource como StaticResource. Obtendrá primer valor. En este caso, VS Designer renderizará el botón como LightGreen aunque en realidad termine como Pink.

StaticResource generará un error cuando se elimine el estilo de nivel raíz (LightGreen).

¿Cuál es la principal diferencia? Me gustan las implicaciones de memoria o rendimiento

La diferencia entre recursos estáticos y dinámicos se produce cuando cambia el objeto subyacente. Si se accedió a su Pincel definido en la colección de Recursos en el código y se estableció en una instancia de objeto diferente, el Rectángulo no detectará este cambio.

Recursos estáticos recuperados una vez por elemento de referencia y utilizados durante la vida útil de los recursos. Mientras que, los recursos dinámicos se recuperan cada vez que se utilizan.

La desventaja de los recursos dinámicos es que tienden a disminuir el rendimiento de la aplicación.

¿Hay reglas en WPF, ya que " los pinceles son siempre estáticos " y " las plantillas son siempre dinámicas " etc.?

La mejor práctica es usar recursos estáticos a menos que haya una razón específica como la que quiere cambiar los recursos en el código detrás de forma dinámica. Otro ejemplo de ejemplo en el que querría usar recursos dinámicos incluye cuando usa los SystemBrushes, SystenFonts y System Parameters.

Encontró todas las respuestas útiles, solo quería agregar un caso de uso más.

En un escenario WPF compuesto, su control de usuario puede hacer uso de los recursos definidos en cualquier otra ventana / control principal (que va a hospedar este control de usuario) al referirse a ese recurso como DynamicResource.

Como lo mencionaron otros, Staticresource se buscará en tiempo de compilación. Los controles de usuario no pueden referirse a aquellos recursos que se definen en el control de alojamiento / control principal. Sin embargo, DynamicResource podría utilizarse en este caso.

Importante beneficio de los recursos dinámicos

si el inicio de la aplicación lleva mucho tiempo, debe usar recursos dinámicos, porque los recursos estáticos siempre se cargan cuando se crea la ventana o aplicación, mientras que los recursos dinámicos se cargan cuando se usan por primera vez.

Sin embargo, no verá ningún beneficio a menos que su recurso sea extremadamente grande y complejo.

Los recursos dinámicos solo se pueden usar cuando la propiedad que se establece está en un objeto que se deriva de un objeto de dependencia o se puede congelar donde los recursos estáticos se pueden usar en cualquier lugar. Puede abstraer todo el control utilizando recursos estáticos.

Los recursos estáticos se utilizan en las siguientes circunstancias:

  1. Cuando no se requieren cambios de recursos de reacción en tiempo de ejecución.
  2. Si necesita un buen rendimiento con muchos recursos.
  3. Al hacer referencia a recursos dentro del mismo diccionario.

Recursos dinámicos:

  1. El valor del tema de establecimiento de propiedad o estilo no se conoce hasta el tiempo de ejecución
    • Esto incluye el sistema, la aplicación, la configuración basada en el tema
    • Esto también incluye referencias avanzadas.
  2. Hacer referencia a recursos grandes que pueden no cargarse cuando se carga la página, las ventanas, el control de usuario.
  3. Hacer referencia a estilos de tema en un control personalizado.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top