¿Cuál es la diferencia entre StaticResource y DynamicResource en WPF?

474

Al utilizar recursos como pinceles, plantillas y estilos en WPF, se pueden especificar como recursos estáticos

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

o como un DynamicResource

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

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

  • Cual es la diferencia principal. Como memoria o implicaciones de rendimiento
  • ¿Existen reglas en WPF como "los pinceles son siempre estáticos" y "las plantillas son siempre dinámicas", etc.?

Yo asumo la elección entre estático vs dinámico no es tan arbitraria como parece ... pero no puedo ver el patrón.

Isak Savo
fuente
27
Es importante tener en cuenta que los desarrolladores de aplicaciones de Windows 8 no tienen DyanmicResource como opción, solo StaticResource.
Jerry Nixon
2
@Jerry Nixon Gracias a Dios por eso, he perdido la cuenta de la cantidad de veces que no pude hacer que nada funcionara porque estaba usando DynamicResource en lugar de StaticResource, o viceversa. Desde el punto de vista de los programadores, esta es una complejidad innecesaria. Una analogía son las definiciones de variables, ¿debería tener que especificar explícitamente si vive en el montón o en la pila? ¿Y si me equivoco arroja un error catastrófico de tiempo de ejecución?
Contango
Para obtener una explicación más completa de StaticResource y DynamicResource, y cuándo usar cada uno, consulte msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx .
Michael Repucci

Respuestas:

466

Un StaticResource se resolverá y asignará a la propiedad durante la carga del XAML que ocurre antes de que la aplicación se ejecute realmente. Solo se asignará una vez y cualquier cambio en el diccionario de recursos se ignorará.

Un DynamicResource asigna un objeto de expresión a la propiedad durante la carga pero en realidad no buscar el recurso hasta el tiempo de ejecución cuando se le pide al objeto de expresión para el valor. Esto difiere buscando el recurso hasta que sea necesario en tiempo de ejecución. Un buen ejemplo sería una referencia directa a un recurso definido más adelante en XAML. Otro ejemplo es un recurso que ni siquiera existirá hasta el tiempo de ejecución. Se actualizará el destino si se cambia el diccionario de recursos de origen.

Phil Wright
fuente
44
¿Qué tiene que cambiar antes de que necesite usar DynamicResource? Tome una plantilla, por ejemplo: la defino una vez, pero luego, por supuesto, los disparadores y otras cosas pueden cambiar el contenido de la plantilla, pero la plantilla sigue siendo la misma. ¿Haría StaticResource aquí?
Isak Savo
55
Use StaticResource si el recurso al que se está conectando está definido en el XAML antes de su punto de uso y no va a cambiar durante la vida útil de la aplicación en ejecución. En ese caso, obtendrá un mejor rendimiento con StaticResource.
Phil Wright,
44
¿Es aplicable la vinculación de dos vías en ambos casos?
WhoIsNinja
11
La última frase es muy importante:It will update the target if the source resource dictionary is changed.
MEMark
44
@IsakSavo Considere una interfaz de usuario con temas de color. Con un recurso dinámico, puede cambiar un diccionario por otro y todo lo que haga referencia a recursos en el nuevo diccionario se actualizará automáticamente.
Gusdor
119

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 usado recursos dinámicos para botones y ventanas y no los he declarado en ninguna parte. En tiempo de ejecución, se verificará el ResourceDictionary de la jerarquía. Dado que no lo he definido, supongo que se usará el valor predeterminado.

Si agrego el código a continuación para hacer clic en el evento del botón, 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 declararse en XAML
  • Y eso también "antes" se usan.

Espero haber aclarado alguna confusión.

Akshay J
fuente
31

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

Afshin
fuente
21
  1. StaticResource usa el primer valor. DynamicResource usa el último valor.
  2. DynamicResource se puede usar para estilos anidados, StaticResource no.

Supongamos que tiene este diccionario de estilo anidado. LightGreen está 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>

En 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 representará el botón como LightGreen, el primer valor que encontró en el estilo. DynamicResource anulará el botón LightGreen como Pink cuando represente la Grid.

StaticResource StaticResource

DynamicResource DynamicResource

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

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

Jeson Martajaya
fuente
13

Cual es la diferencia principal. Como memoria o implicaciones de rendimiento

La diferencia entre los 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 código y se estableció en una instancia de objeto diferente, 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, DynamicResources recupera cada vez que se utilizan.

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

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

La mejor práctica es utilizar recursos estáticos a menos que exista una razón específica como que desee cambiar los recursos en el código de forma dinámica. Otro ejemplo de instancia en la que desearía utilizar recursos dinámicos incluye cuando utiliza SystemBrushes, SystenFonts y System Parameters.

CharithJ
fuente
7

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

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

Como han mencionado otros, se buscará Staticresource en tiempo de compilación. Los controles de usuario no pueden referirse a los recursos que se definen en el control de alojamiento / padre. Sin embargo, DynamicResource podría usarse en este caso.

Manish Basantani
fuente
3

Beneficio importante 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 la 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.

zamoldar
fuente
Para DynamicResources, ¿está creando un problema de rendimiento solo una vez (se usa por primera vez) o cada vez que se usa el elemento?
Morgane
en este caso, los campos más utilizados deben ser recurso estático, a medida campos utilizados pueden ser dinámicos, es decir, para los recursos de ventana principal son estáticos y recursos ventana de diálogo pueden ser dinámicos
zamoldar
2

Los recursos dinámicos solo se pueden usar cuando la propiedad que se establece está en un objeto derivado de un objeto de dependencia o congelable, 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 el recurso de reacción cambia en tiempo de ejecución no es necesario.
  2. Si necesita un buen rendimiento con muchos recursos.
  3. Mientras hace 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 temas
    • Esto también incluye referencias directas.
  2. Hacer referencia a grandes recursos que pueden no cargarse cuando se cargan páginas, ventanas y control de usuario.
  3. Hacer referencia a estilos de tema en un control personalizado.
iaminvinicble
fuente