WPF中动态静态资源(StaticResource)与资源(DynamicResource)详解
一、核心区别
特性 | 静态资源(StaticResource) | 动态资源(DynamicResource) |
---|---|---|
解析时机 | 编译时解析(首次加载时确定值) | 运行时解析(首次使用时才确定值) |
更新机制 | 资源变化后,引用不会更新 | 资源变化后,引用会自动更新 |
性能 | 略高(仅解析一次) | 略低(运行时需维护引用关系) |
适用场景 | 资源固定不变(如基础样式、固定图片) | 资源可能动态变化(如主题切换、多语言) |
二、经典示例
下面通过一个"主题切换"场景,直观展示两者的区别:
1. 定义资源字典(主题资源)
先创建两个资源字典(浅色/深色主题),存储颜色资源:
LightTheme.xaml(浅色主题):
xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<SolidColorBrush x:Key="BgColor" Color="White"/>
<SolidColorBrush x:Key="TextColor" Color="Black"/>
</ResourceDictionary>
DarkTheme.xaml(深色主题):
xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<SolidColorBrush x:Key="BgColor" Color="Gray"/>
<SolidColorBrush x:Key="TextColor" Color="White"/>
</ResourceDictionary>
2. 主窗口XAML(引用资源)
在窗口中分别用静态资源和动态资源引用主题颜色,并添加切换按钮:
xml
<Window x:Class="ResourceDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="资源示例" Height="300" Width="400">
<!-- 初始加载浅色主题 -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="LightTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel Margin="20">
<!-- 静态资源引用(不会随主题变化) -->
<TextBlock Text="静态资源文本"
Foreground="{StaticResource TextColor}"
FontSize="16" Margin="5"/>
<!-- 动态资源引用(会随主题变化) -->
<TextBlock Text="动态资源文本"
Foreground="{DynamicResource TextColor}"
FontSize="16" Margin="5"/>
<!-- 背景色用动态资源(方便观察整体变化) -->
<StackPanel Background="{DynamicResource BgColor}" Padding="10" Margin="5">
<Button Content="切换到深色主题" Click="SwitchToDarkTheme" Margin="5"/>
<Button Content="切换到浅色主题" Click="SwitchToLightTheme" Margin="5"/>
</StackPanel>
</StackPanel>
</Window>
3. 后台代码(切换主题)
通过替换资源字典实现主题切换:
csharp
using System.Windows;
namespace ResourceDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// 切换到深色主题
private void SwitchToDarkTheme(object sender, RoutedEventArgs e)
{
UpdateTheme("DarkTheme.xaml");
}
// 切换到浅色主题
private void SwitchToLightTheme(object sender, RoutedEventArgs e)
{
UpdateTheme("LightTheme.xaml");
}
// 更新资源字典
private void UpdateTheme(string themePath)
{
// 清除现有主题资源
Resources.MergedDictionaries.Clear();
// 加载新主题
Resources.MergedDictionaries.Add(new ResourceDictionary
{
Source = new Uri(themePath, UriKind.Relative)
});
}
}
}
三、运行效果
- 初始状态:两个文本均为黑色(浅色主题)。
- 点击"切换到深色主题":
- 静态资源文本:仍为黑色(未更新)。
- 动态资源文本:变为白色(随资源更新)。
- 背景色变为灰色(动态资源生效)。
- 切换回浅色主题时,动态资源文本和背景色会再次更新,静态资源文本保持不变。
四、关键结论
- 静态资源 适合引用不会变化的资源(如固定样式、图标),性能更优。
- 动态资源 适合引用可能动态修改的资源(如主题、多语言字符串),但会有轻微性能开销。
- 实际开发中,优先用静态资源,仅在需要动态更新时使用动态资源。