您的位置:首页 > 其它

StaticResource vs DynamicResource

2014-08-18 16:50 483 查看

StaticResource

Provides a value for any XAML property
attribute by looking up a reference to an already defined resource. Lookup
behavior for that resource is analogous to load-time lookup, which will look for resources that were previously loaded from the markup of the current XAML page as well as other application sources, and will generate that resource value as the property value
in the run-time objects.

A StaticResource must
not attempt to make a forward reference to a resource that is defined lexically further within the XAML file. Attempting
to do so is not supported, and even if such a reference does not fail, attempting the forward reference will incur a load time performance penalty when the internal hash tables representing a ResourceDictionary are
searched. For
best results, adjust the composition of your resource dictionaries
such that forward references can be avoided. If
you cannot avoid a forward reference, use DynamicResource Markup Extension instead.

Static
resource references work best for the following circumstances:

Your
application design concentrates most of all of its resources into page or application level resource dictionaries. Static
resource references are not reevaluated based on runtime behaviors such as reloading a page, and therefore there can be some performance benefit to avoiding large numbers of dynamic resource references when they are not necessary per your resource and application
design.
You are setting
the value of a property that is not on a DependencyObject or
a Freezable.
You are creating a resource dictionary
that will be compiled into a DLL, and packaged as part of the application or shared between applications.
You
are creating a theme for a custom control, and are defining resources that are used within the themes. For
this case, you typically do not want the dynamic resource reference lookup behavior, you instead want the static resource reference behavior so that the lookup is predictable and self-contained to the theme. With
a dynamic resource reference, even a reference within a theme is left unevaluated until runtime, and there is a chance that when the theme is applied, some local element will redefine a key that your theme is trying to reference, and the local element will
fall prior to the theme itself in the lookup.If
that happens, your theme will not behave in an expected manner.
You
are using resources to set large numbers of dependency properties. Dependency
properties have effective value caching as enabled by the property system, so if you provide a value for a dependency property that can be evaluated at load time, the dependency property does not have to check for a reevaluated expression and can return the
last effective value. This
technique can be a performance benefit.
You want to change
the underlying resource for all consumers, or you want to maintain separate writable instances for each consumer by using the x:Shared
Attribute.

Static resource lookup behavior:

The lookup process checks for the requested key within the resource
dictionary defined by the element that sets the property.
The lookup process then traverses the
logical tree upward, to the parent element and its resource dictionary. This
continues until the root element is reached.
Next, application resources are checked. Application
resources are those resources within the resource dictionary that is defined by the Application object
for your WPF application.

Static resource references from within
a resource dictionary must reference a resource that has already been defined lexically before the resource reference. Forward
references cannot be resolved by a static resource reference. For
this reason, if you use static resource references, you must design your resource dictionary structure such that resources intended for by-resource use are defined at or near the beginning of each respective resource dictionary.
Static resource lookup can extend into
themes, or into system resources, but this is supported only because the XAML loader defers the request. The
deferral is necessary so that the runtime theme at the time the page loads applies properly to the application. However,
static resource references to keys that are known to only exist in themes or as system resources are not recommended. This
is because such references are not reevaluated if the theme is changed by the user in realtime. A
dynamic resource reference is more reliable when you request theme or system resources. The
exception is when a theme element itself requests another resource. These
references should be static resource references, for the reasons mentioned earlier.

The exception behavior if a static resource reference is not found varies. If the resource was deferred, then the exception occurs at runtime. If
the resource was not deferred, the exception occurs at load time.

DynamicResource

Provides
a value for any XAML property attribute by deferring that value to be a reference to a defined resource. Lookup
behavior for that resource is analogous to run-time lookup.

A DynamicResource will
create a temporary expression during the initial compilation and thus defer lookup for resources until the requested resource value is actually required in order to construct an object. This
may potentially be after the XAML page is loaded. The
resource value will be found based on key search against all active resource dictionaries starting from the current page scope, and is substituted for the placeholder expression from compilation.
Dynamic resources work best for the following circumstances:

The value of the resource depends on conditions that are not known until runtime. This
includes system resources, or resources that are otherwise user settable. For example, you can create setter values that
refer to system properties, as exposed by SystemColors, SystemFonts,
or SystemParameters. These
values are truly dynamic because they ultimately come from the runtime environment of the user and operating system. You
might also have application-level themes that can change, where page-level resource access must also capture the change.
You are creating or referencing theme styles for a custom control.
You intend to adjust the contents of a ResourceDictionary during
an application lifetime.
You have a complicated resource structure that has interdependencies, where a forward reference may be required. Static
resource references do not support forward references, but dynamic resource references do support them because the resource does not need to be evaluated until runtime, and forward references are therefore not a relevant concept.
You are referencing a resource that is particularly large from the perspective of a compile or working set, and the resource might not be used immediately when the page loads. Static
resource references always load from XAML when the page loads; however, a dynamic resource reference does not load until it is actually used.
You are creating a style where setter values might come from other values that are influenced by themes or other user settings.
You are applying resources to elements that might be reparented in the logical tree during application lifetime. Changing
the parent also potentially changes the resource lookup scope, so if you want the resource for a reparented element to be reevaluated based on the new scope, always use a dynamic resource reference.

Dynamic resource lookup behavior: Resource lookup behavior for a dynamic resource reference parallels the lookup behavior in your code if you call FindResource or SetResourceReference.

The lookup process checks for the requested key within the resource dictionary defined by the element that sets the property.

If the element defines a Style property,
the Resources dictionary
within the Style is checked.
If the element defines a Template property,
the Resources dictionary
within the FrameworkTemplate is
checked.

The lookup process then traverses the logical tree upward, to the parent element and its resource dictionary. This
continues until the root element is reached.
Next, application resources are checked. Application
resources are those resources within the resource dictionary that is defined by the Application object
for your WPF application.
Theme resource dictionary is checked, for the currently active theme. If
the theme changes at runtime, the value is reevaluated.
System resources are checked.

Exception behavior (if any) varies:

If a resource was requested by a FindResource call,
and was not found, an exception is raised.
If a resource was requested by a TryFindResource call,
and was not found, no exception is raised, but the returned value is null. If the property
being set does not accept null, then it is still possible that a deeper exception will be raised (this depends on the individual property being set).
If a resource was requested by a dynamic resource reference in XAML, and was not found, then the behavior depends on the general property system, but the general behavior is as if no property setting
operation occurred at the level where the resource exists. For instance, if you attempt to set the background on a an individual button element using a resource
that could not be evaluated, then no value set results, but the effective value can still come from other participants in the property system and value precedence. For
instance, the background value might still come from a locally defined button style, or from the theme style. For properties that are not defined by theme
styles, the effective value after a failed resource evaluation might come from the default value in the property metadata.

Dynamic resource references have some notable restrictions. At
least one of the following must be true:

The property being set must be a property on a FrameworkElement or FrameworkContentElement. That
property must be backed by a DependencyProperty.
The reference is for a value within a Style Setter.
The property being set must be a property on a Freezable that
is provided as a value of either a FrameworkElement or FrameworkContentElement property,
or a Setter value.

Because the property being set must be a DependencyProperty or Freezable property,
most property changes can propagate to UI because a property change (the changed dynamic resource value) is acknowledged by the property system. Most
controls include logic that will force another layout of a control if a DependencyProperty changes
and that property might affect layout. However, not all properties that have aDynamicResource
Markup Extension as their value are guaranteed to provide the value in such a way that they update in realtime in the UI. That
functionality still might vary depending on the property, as well as depending on the type that owns the property, or even the logical structure of your application.

Summary

The difference between
StaticResource
and
DynamicResource
lies
in how the resources are retrieved by the referencing elements.
StaticResource
are
retrieved only once by the referencing element and used for entire life of the resource. On the other hand,
DynamicResource
are
acquired every time the referenced object is used.
The demerit of
DynamicResource
is
that it reduces application performance because resources are retrieved every time they are used. The best practice is to
StaticResource
use
until there is a specific reason to use
DynamicResource
.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: