English 中文(简体)
在WPF中,StaticResource和DynamicResource有什么区别?
原标题:
  • 时间:2008-10-14 11:54:57
  •  标签:

在WPF中使用像刷子、模板、样式等资源时,它们可以作为StaticResources进行指定。

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

或作为DynamicResource

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

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

  • 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.?

我认为静态与动态之间的选择并不像看起来那么随意,但我无法看到模式。

最佳回答

在XAML加载期间(实际应用程序运行之前),将解析并分配StaticResource到属性中。它只会被分配一次,任何资源字典的更改都会被忽略。

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:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

这里我使用了动态资源来指定按钮和窗口,并没有在任何地方声明过。在运行时,将会检查层次结构的 ResourceDictionary,由于我没有定义,所以应该会使用默认值。

如果我将下面的代码添加到按钮的点击事件中,由于它们使用DynamicResource,背景将相应地更新。

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

如果他们使用了StaticResource:

  • The resource has to be declared in XAML
  • And that too "before" they are used.

希望我消除了一些困惑。

StaticResource will be resolved on object construction.
DynamicResource will be evaluated and resolved every time control needs the resource.

  1. StaticResource uses first value. DynamicResource uses last value.
  2. DynamicResource can be used for nested styling, StaticResource cannot.

假设您有这个嵌套样式字典。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>

在视图中:

<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将把按钮呈现为LightGreen,其中它找到的样式的第一个值。DynamicResource将覆盖LightGreen按钮,同时呈现网格为Pink。

StaticResource StaticResource

DynamicResource DynamicResource

请记住,VS Designer 将 DynamicResource 视为 StaticResource。 它将获取第一个值。 在这种情况下,虽然实际颜色为 Pink,但 VS Designer 将以 LightGreen 的颜色呈现按钮。

当移除根级样式(LightGreen)时,StaticResource 将会抛出错误。

主要的区别是什么?例如内存或性能的影响。

静态资源和动态资源之间的区别在于基础对象发生变化时。如果在代码中访问在资源集合中定义的Brush并将其设置为不同的对象实例,则Rectangle不会检测到此更改。

静态资源只需要引用元素一次便可在资源的生命周期内使用。而动态资源每次使用时都需要重新获取。

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

WPF中是否有规则,例如“笔刷始终是静态的”和“模板始终是动态的”等?

最佳做法是使用静态资源,除非有特定的原因,例如您想在代码后台动态更改资源。您还希望使用动态资源的另一个示例是当您使用SystemBrushes、SystenFonts和System Parameters时。

发现所有答案都有用,只是想添加一个更多的用例。

在复合WPF场景中,您的用户控件可以使用任何其他父窗口/控件中定义的资源(即将托管该用户控件的窗口/控件),方法是将该资源引用为DynamicResource。

正如其他人所提到的,Staticresource将在编译时查找。用户控件不能引用在托管/父控件中定义的这些资源。不过,此情况下可以使用DynamicResource。

动态资源的重要优势

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.

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.

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

  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.

动态资源:

  1. Value of property or style setter theme is not known until runtime
    • This include system, aplication, theme based settings
    • This also includes forward references.
  2. Referencing large resources that may not load when page, windows, usercontrol loads.
  3. Referencing theme styles in a custom control.




相关问题
热门标签