StaticResource和WPF中的DynamicResource有什么区别?

在WPF中使用资源(如画笔,模板和样式)时,可以将它们指定为StaticResources

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

或者作为一个DynamicResource

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

大多数时候(总是?),只有一个工作,另一个会在运行时抛出exception。 但是我想知道为什么:

  • 主要区别是什么? 像内存或性能影响
  • WPF中有像“画笔总是静态”和“模板总是dynamic的”等规则吗?

认为静态与dynamic之间的select并不像看起来那么武断……但我看不到这种模式。

在加载实际运行应用程序之前发生的XAML期间, StaticResource将被parsing并分配给属性。 它只会被分配一次,任何对资源字典的更改都会被忽略。

DynamicResource在加载期间将一个Expression对象分配给该属性,但直到运行时才会查询该资源,此时需要Expression对象的值。 这延缓查找资源,直到在运行时需要它。 一个很好的例子就是对后面在XAML中定义的资源的前向引用。 另一个例子是直到运行时才会存在的资源。 如果源资源字典发生更改,它将更新目标。

我也对他们感到困惑。 看下面这个例子:

 <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:,,,http://img.dovov.comwinter.jpg"></Image> </StackPanel> <Window.Background> <DynamicResource ResourceKey="PinkBrush"></DynamicResource> </Window.Background> </Window> 

在这里,我已经使用了button和窗口的dynamic资源,并没有在任何地方声明它。运行时,层次结构的ResourceDictionary将被检查。由于我没有定义它,我想默认会被使用。

如果我添加下面的代码来点击Button的事件,因为他们使用DynamicResource,所以后台会相应地更新。

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

如果他们使用了StaticResource:

  • 资源必须在XAML中声明
  • 而且在他们使用之前也是如此。

希望我清除一些混乱。

StaticResource将在对象构造上parsing。
每当控制需要资源时,DynamicResource将被评估和解决。

逻辑资源允许您在XAML中定义对象,这些对象不是可视化树的一部分,但可以在用户界面中使用。 其中一个逻辑资源的例子是Brush,用来提供配色scheme。 通常,这些对象被定义为由应用程序的多个元素使用的资源。

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

现在,上面声明的资源可以用作静态或dynamic资源。 需要记住的一点是,在使用静态资源时,应该首先在XAML代码中定义它,然后才能参考。 静态和dynamic资源可以用作:

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

要么:

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

StaticResource和DynamicResource的区别在于资源是如何被引用元素检索的。 StaticResource只被引用元素检索一次,并用于资源的整个生命周期。 另一方面,每当使用被引用的对象时就获取DynamicResource。

简单来说,如果RadialGradientBrush的颜色属性在代码中被更改为橙色和粉红色,那么只有当资源被用作DynamicResource时,它才会反映在元素上。 以下是更改代码中资源的代码:

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

DynamicResource的缺点是它会降低应用程序性能,因为每次使用资源时都会检索它们。 最好的做法是静态资源使用,直到有一个特定的原因使用DynamicResource。

资源:
WPF:StaticResource与DynamicResource

  1. StaticResource使用第一个值。 DynamicResource使用最后一个值。
  2. DynamicResource可以用于嵌套样式,StaticResource不能。

假设你有这个嵌套的样式字典。 LightGreen在底层,Pink则嵌套在网格中。

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

鉴于:

 <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会将该button渲染为LightGreen,这是它在样式中find的第一个值。 DynamicResource会在呈现Grid时将“LightGreen”button重写为“Pink”。

静态资源 静态资源

DynamicResource DynamicResource

请记住,VSdevise器将DynamicResource视为StaticResource。 它会得到第一个价值。 在这种情况下,VS Designer会将该button渲染为LightGreen,尽pipe它实际上以Pink结束。

当根级别样式(LightGreen)被移除时,StaticResource会引发错误。

主要区别是什么? 像内存或性能影响

静态和dynamic资源之间的区别来自于底层对象的变化。 如果在资源集合中定义的画笔在代码中被访问并设置为不同的对象实例,则矩形将不会检测到此更改。

静态资源通过引用元素检索一次,并用于资源的生命周期。 而DynamicResources则在每次使用时检索。

dynamic资源的缺点是它们往往会降低应用程序的性能。

WPF中有像“画笔总是静态”和“模板总是dynamic的”等规则吗?

最好的做法是使用静态资源,除非有特定的原因,比如你想dynamic改变代码中的资源。 您要使用dynamic资源的实例的另一个示例包括使用SystemBrushes,SystenFonts和System Parameters时的情况。

find所有有用的答案,只是想添加一个用例。

在复合WPF场景中,用户控件可以通过将该资源引用为DynamicResource来利用在其他父窗口/控件(即要托pipe该用户控件)中定义的资源。

正如其他人所提到的,Staticresource将在编译时查询。 用户控件不能引用在宿主/父控件中定义的那些资源。 虽然在这种情况下可以使用DynamicResource。

dynamic资源的重要好处

如果应用程序启动需要很长时间,则必须使用dynamic资源,因为静态资源始终在创build窗口或应用程序时加载,而dynamic资源在首次使用时加载。

但是,除非您的资源非常庞大而复杂,否则您将不会看到任何好处。

StaticResource和DynamicResource的区别在于资源是如何被引用元素检索的。 StaticResource只被引用元素检索一次,并用于资源的整个生命周期。 另一方面,每当使用被引用的对象时就获取DynamicResource。

以下是静态和dynamic资源的主要区别:

  1. 静态资源只会评估一次资源,而每次需要资源时都会评估dynamic资源。

2.dynamic资源比静态资源具有更多的性能开销,因为每次请求或需要时都会查找资源。

3.静态资源比dynamic资源更快,但加载页面或窗口花费的时间更less,因为实际使用dynamic资源时会加载dynamic资源。

静态引用的资源只对资源进行一次评估,之后如果资源发生变化,这些更改不会反映在绑定中。 每当需要资源时,评估dynamic引用的资源。

dynamic资源只能在被设置的属性是从依赖项对象派生的对象或可以在任何地方使用静态资源的可冻结对象时使用。 您可以使用静态资源抽象出整个控件。

在以下情况下使用静态资源:

  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.