.net WPF中的StaticResource和DynamicResource有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/200839/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between StaticResource and DynamicResource in WPF?
提问by Isak Savo
When using resources such as brushes, templates and styles in WPF, they can be specified either as StaticResources
在 WPF 中使用画笔、模板和样式等资源时,可以将它们指定为 StaticResources
<Rectangle Fill="{StaticResource MyBrush}" />
or as a DynamicResource
或作为动态资源
<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}" />
Most of the times (always?), only one works and the other will throw exception during runtime. But I'd like to know why:
大多数时候(总是?),只有一个有效,另一个会在运行时抛出异常。但我想知道为什么:
- What is the main difference. Like memory or performance implications
- Are there rules in WPF like "brushes are always static" and "templates are always dynamic" etc.?
- 主要区别是什么。像内存或性能影响
- WPF 中是否有“画笔始终是静态的”和“模板始终是动态的”等规则?
I assumethe choice between Static vs Dynamic isn't as arbitrary as it seems... but I fail to see the pattern.
我认为静态与动态之间的选择并不像看起来那么随意……但我看不到这种模式。
采纳答案by Phil Wright
A StaticResourcewill be resolved and assigned to the property during the loading of the XAML which occurs before the application is actually run. It will only be assigned once and any changes to resource dictionary ignored.
一个静态资源将得到解决,并且应用程序实际运行前发生的XAML负荷期间分配给属性。它只会被分配一次,并且忽略对资源字典的任何更改。
A DynamicResourceassigns an Expression object to the property during loading but does not actually lookup the resource until runtime when the Expression object is asked for the value. This defers looking up the resource until it is needed at runtime. A good example would be a forward reference to a resource defined later on in the XAML. Another example is a resource that will not even exist until runtime. It will update the target if the source resource dictionary is changed.
一个DynamicResource装载过程中分配一个表达式对象的属性,但实际上并没有查找资源直到运行时表达式对象要求的值。这会推迟查找资源,直到在运行时需要它。一个很好的例子是对稍后在 XAML 中定义的资源的前向引用。另一个例子是直到运行时才会存在的资源。如果源资源字典发生更改,它将更新目标。
回答by Akshay J
I was also confused about them. See this example below:
我也对他们感到困惑。请参阅下面的示例:
<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>
Here I have used dynamic resource for button and window and have not declared it anywhere.Upon runtime, the ResourceDictionary of the hierarchy will be checked.Since I have not defined it, I guess the default will be used.
这里我对按钮和窗口使用了动态资源,并没有在任何地方声明它。运行时,将检查层次结构的ResourceDictionary。由于我没有定义它,我猜会使用默认值。
If I add the code below to click event of Button, since they use DynamicResource, the background will be updated accordingly.
如果我将下面的代码添加到 Button 的单击事件中,由于它们使用 DynamicResource,背景将相应地更新。
private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
this.Resources.Add( "PinkBrush"
,new SolidColorBrush(SystemColors.DesktopColor)
);
}
If they had used StaticResource:
如果他们使用了 StaticResource:
- The resource has to be declared in XAML
- And that too "before" they are used.
- 必须在 XAML 中声明资源
- 这也是“之前”使用它们。
Hope I cleared some confusion.
希望我清除了一些困惑。
回答by Afshin
StaticResource will be resolved on object construction.
DynamicResource will be evaluated and resolved every time control needs the resource.
StaticResource 将在对象构造上解析。
每次控件需要资源时,都会评估和解析 DynamicResource。
回答by Jeson Martajaya
- StaticResource uses firstvalue. DynamicResource uses lastvalue.
- DynamicResource can be used for nested styling, StaticResource cannot.
- StaticResource 使用第一个值。DynamicResource 使用最后一个值。
- DynamicResource 可用于嵌套样式,而 StaticResource 不能。
Suppose you have this nested Style dictionary. LightGreen is at the root level while Pink is nested inside a Grid.
假设您有这个嵌套的 Style 字典。LightGreen 位于根级别,而 Pink 嵌套在 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>
In view:
鉴于:
<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 will render the button as LightGreen, the first value it found in the style. DynamicResource will override the LightGreen button as Pink as it renders the Grid.
StaticResource 会将按钮呈现为 LightGreen,这是它在样式中找到的第一个值。DynamicResource 将在渲染网格时将 LightGreen 按钮覆盖为粉红色。
StaticResource
静态资源
DynamicResource
动态资源
Keep in mind that VS Designer treats DynamicResource as StaticResource. It will get first value. In this case, VS Designer will render the button as LightGreen although it actually ends up as Pink.
请记住,VS Designer 将 DynamicResource 视为 StaticResource。它将获得第一个值。在这种情况下,VS Designer 会将按钮呈现为浅绿色,尽管它实际上最终为粉红色。
StaticResource will throw an error when the root-level style (LightGreen) is removed.
当根级样式 (LightGreen) 被移除时,StaticResource 将抛出错误。
回答by CharithJ
What is the main difference. Like memory or performance implications
主要区别是什么。像内存或性能影响
The difference between static and dynamic resources comes when the underlying object changes. If your Brush defined in the Resources collection were accessed in code and set to a different object instance, Rectangle will not detect this change.
当底层对象发生变化时,静态资源和动态资源之间的区别就出现了。如果您在 Resources 集合中定义的 Brush 在代码中被访问并设置为不同的对象实例,则 Rectangle 将不会检测到此更改。
Static Resources retrieved once by referencing element and used for the lifetime of the resources. Whereas, DynamicResources retrieve every time they are used.
静态资源通过引用元素检索一次并用于资源的生命周期。而 DynamicResources 每次使用时都会检索。
The downside of Dynamic resources is that they tend to decrease application performance.
动态资源的缺点是它们往往会降低应用程序性能。
Are there rules in WPF like "brushes are always static" and "templates are always dynamic" etc.?
WPF 中是否有“画笔始终是静态的”和“模板始终是动态的”等规则?
The best practice is to use Static Resources unless there is a specific reason like you want to change resource in the code behind dynamically. Another example of instance in which you would want t to use dynamic resoruces include when you use the SystemBrushes, SystenFonts and System Parameters.
最佳实践是使用静态资源,除非有特定原因,例如您想动态更改代码中的资源。另一个不希望使用动态资源的实例包括当您使用 SystemBrushes、SystenFonts 和 System Parameters 时。
回答by Manish Basantani
Found all answers useful, just wanted to add one more use case.
发现所有答案都很有用,只是想再添加一个用例。
In a composite WPF scenario, your user control can make use of resources defined in any other parent window/control (that is going to host this user control) by referring to that resource as DynamicResource.
在复合 WPF 方案中,您的用户控件可以通过将该资源称为 DynamicResource 来使用在任何其他父窗口/控件(将承载此用户控件)中定义的资源。
As mentioned by others, Staticresource will be looked up at compile time. User controls can not refer to those resources which are defined in hosting/parent control. Though, DynamicResource could be used in this case.
正如其他人所提到的,静态资源将在编译时被查找。用户控件不能引用宿主/父控件中定义的那些资源。不过,在这种情况下可以使用 DynamicResource。
回答by zamoldar
Important benefit of the dynamic resources
动态资源的重要好处
if application startup takes extremely long time, you must use dynamic resources, because static resources are always loaded when the window or app is created, while dynamic resources are loaded when they're first used.
如果应用程序启动时间非常长,则必须使用动态资源,因为静态资源总是在创建窗口或应用程序时加载,而动态资源在首次使用时加载。
However, you won't see any benefit unless your resource is extremely large and complex.
但是,除非您的资源非常庞大和复杂,否则您不会看到任何好处。
回答by iaminvinicble
Dynamic resources can only be used when property being set is on object which is derived from dependency object or freezable where as static resources can be used anywhere. You can abstract away entire control using static resources.
动态资源只能在设置的属性位于从依赖对象或freezable 派生的对象上时才能使用,而静态资源可以在任何地方使用。您可以使用静态资源抽象出整个控制。
Static resources are used under following circumstances:
静态资源在以下情况下使用:
- When reaction resource changes at runtime is not required.
- If you need a good performance with lots of resources.
- While referencing resources within the same dictionary.
- 当不需要在运行时更改反应资源时。
- 如果您需要具有大量资源的良好性能。
- 在引用同一词典中的资源时。
Dynamic resources:
动态资源:
- Value of property or style setter theme is not known until runtime
- This include system, aplication, theme based settings
- This also includes forward references.
- Referencing large resources that may not load when page, windows, usercontrol loads.
- Referencing theme styles in a custom control.
- 直到运行时才知道属性或样式设置器主题的值
- 这包括系统、应用程序、基于主题的设置
- 这也包括前向引用。
- 引用页面、窗口、用户控件加载时可能无法加载的大型资源。
- 在自定义控件中引用主题样式。

