2008-10-14 18 views
394

Al utilizar recursos tales como pinceles, plantillas y estilos en WPF, que se puede especificar como StaticResources¿Cuál es la diferencia entre StaticResource y DynamicResource en WPF?

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

o como DynamicResource

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

La mayoría de las veces (siempre?), Sólo se uno funciona y el otro arrojará excepciones durante el tiempo de ejecución. Pero me gustaría saber por qué:

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

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

+24

Es importante tener en cuenta que los desarrolladores de aplicaciones de Windows 8 no tienen DyanmicResource como opción, solo StaticResource. –

+2

@Jerry Nixon Gracias a Dios por eso, he perdido la cuenta de la cantidad de veces que no pude hacer nada para trabajar 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, ¿debo especificar explícitamente si vive en el montón o en la pila? Y si lo hago mal, ¿arroja un error de tiempo de ejecución catastrófico? – Contango

+0

Para obtener una explicación más detallada de StaticResource y DynamicResource, y cuándo usar cada una, consulte https://msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx. –

Respuesta

394

A StaticResource se resolverán y se asignarán 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 se ignorarán los cambios al diccionario de recursos.

A DynamicResource asigna un objeto Expression a la propiedad durante la carga pero en realidad no busca el recurso hasta el tiempo de ejecución cuando se solicita el valor al objeto Expression. Esto posterga la búsqueda del 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. Actualizará el objetivo si se cambia el diccionario de recursos de origen.

+4

¿Qué tiene que cambiar antes de necesitar usar DynamicResource? Tomemos una plantilla, por ejemplo: la defino una vez pero luego, por supuesto, los desencadenantes y otras cosas pueden cambiar el contenido de la plantilla, pero la plantilla sigue siendo la misma. ¿StaticResource lo haría aquí? –

+4

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 el tiempo de vida de la aplicación en ejecución. En ese caso, obtienes un mejor rendimiento con StaticResource. –

+4

tiene un enlace de dos vías aplicable a ambos, en caso afirmativo, ¿cuál sería la diferencia en ese caso? – WhoIsNinja

27

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

102

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 dinámica de recursos para el botón y la ventana y no lo han declarado anywhere.Upon tiempo de ejecución, el ResourceDictionary de la jerarquía será checked.Since no he definido, supongo el predeterminado será usado.

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

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

Si se hubieran utilizado StaticResource:

  • El recurso tiene que ser declarado en XAML
  • Y eso también "antes" que se utilizan.

Espero haber eliminado la confusión.

23

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, por encima de los recursos declarados podría ser utilizado ya sea como recurso estático o dinámico. Un punto para recordar es que, al usar recursos estáticos, primero debe definirse en código XAML, antes de poder referirse. 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 radica en cómo los recursos son recuperados por los elementos de referencia. StaticResource se recupera solo una vez mediante el elemento de referencia y se usa durante toda la vida útil del recurso. Por otro lado, DynamicResource se adquiere cada vez que se utiliza el objeto al que se hace referencia.

Poniéndolo de manera más simple, si la propiedad de color de RadialGradientBrush cambia en el 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 de código:

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

El demérito de DynamicResource es que reduce el rendimiento de aplicaciones ya que los recursos se recuperan cada vez que se utilizan. La mejor práctica es utilizar StaticResource hasta que haya una razón específica para usar DynamicResource.

Fuente:
WPF: StaticResource vs. DynamicResource

+2

La explicación en el código fuente es excelente, pero copiar y pegar especialmente sin hacer referencia a él por el contestador original (fue agregado por la edición de @ Em1) es MALO. Por lo tanto, la respuesta es excelente, pero ni siquiera se puede subir de categoría –

+0

Solo para confirmar. Vi el "problema de rendimiento" en todas partes, es un problema de rendimiento cada vez que se carga el elemento, ¿verdad? ¿O es un problema de Perfermance solo una vez (cuando se inicia la aplicación)? – Morgane

13

¿Cuál es la principal diferencia. Como implicaciones de memoria o rendimiento

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

Recursos estáticos recuperados una vez haciendo referencia al elemento y se utilizan durante el tiempo de vida 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.

¿Hay 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 haya una razón específica para cambiar dinámicamente el recurso del código subyacente. Otro ejemplo de instancia en la que desearía usar resoruces dinámicas incluye cuando usa los SystemBrushes, SystenFonts y los parámetros del sistema.

7

Se encontraron 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 recursos definidos en cualquier otra ventana/control principal (que va a hospedar este control de usuario) al referirse a ese recurso como DynamicResource.

Como se mencionó por otros, se buscará Staticresource en tiempo de compilación. Los controles de usuario no pueden hacer referencia a los recursos que están definidos en el control de hosting/principal.Sin embargo, DynamicResource podría ser utilizado en este caso.

3

importantes en los beneficios de los recursos dinámicos

si inicio de la aplicación lleva tiempo extremadamente largo, debe utilizar los 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 primero se usan.

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

+0

Para DynamicResources, ¿está creando un problema de rendimiento solo una vez (usado por primera vez) o es cada vez que se usa el elemento? – Morgane

+0

en este caso, la mayoría de los campos usados ​​deben ser recursos estáticos, los campos personalizados utilizados pueden ser dinámicos, es decir, los recursos de la ventana principal son estáticos y el recurso de la ventana de diálogo puede ser dinámico – zamoldar

2

La diferencia entre StaticResource y DynamicResource radica en cómo los recursos son recuperados por los elementos de referencia. StaticResource se recupera solo una vez mediante el elemento de referencia y se usa durante toda la vida útil del recurso. Por otro lado, DynamicResource se adquiere cada vez que se utiliza el objeto al que se hace referencia.

2

A continuación se presentan la mayor diferencia entre los recursos estáticos y dinámicos:

  1. recurso estático evaluará el recurso sólo una vez, mientras dinámica de recursos será evaluado cada vez que necesita el recurso.

2.El recurso dinámico tiene más sobrecarga de rendimiento que los recursos estáticos porque busca recursos cada vez que lo solicita o necesita.

3.El recurso estático es más rápido, pero lleva un poco más de tiempo cargar la página o ventana que el recurso dinámico porque los recursos dinámicos se cargan cuando realmente los usa.

17
  1. StaticResource utiliza primer valor. DynamicResource usa último valor de.
  2. DynamicResource se puede utilizar para el estilo anidado, StaticResource no.

Supongamos que tiene este diccionario de estilos anidados. LightGreen está en el nivel raíz mientras Pink está anidado dentro de una Grilla.

<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 hará que el botón como verde claro, el primer valor se encuentra en el estilo. DynamicResource anulará el botón LightGreen como rosa, ya que representa la cuadrícula.

StaticResource StaticResource

DynamicResource DynamicResource

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

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

1

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

recursos estáticos se utilizan en virtud de las circunstancias siguientes:

 1.When reaction resource changes at runtime is not required. 
     2.If you need a good performance with lots of resources. 
     3.While referencing resources within the same dictionary. 

Dynamic resources: 
    1.Value of property or style setter theme is not known untill runtime 
     a. This include system ,aplication,theme based settings 
     b. This also includes forward references. 

    2.Referencing large resources that may not load when page,windows,usercontrol loads . 

    3. Referncing theme styles in a custom control. 
0

estático referidos recursos de evaluar el recurso sólo una vez y después de eso, si cambian los recursos de esos cambios no se reflejan en la unión. Mientras que los recursos referidos dinámicos se evalúan cada vez que se necesita el recurso.

Cuestiones relacionadas