一、WPF资源介绍
WPF中的资源是指在应用程序中定义的可重用对象,包括字符串、画刷、图像、样式、模板等任意CLR对象。资源可以在应用程序中的多个地方共享和重用,从而提高了应用程序的可维护性和可扩展性。
官方文档:https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/resources-wpf
Resources为ResourceDictionary类的对象,提供一个哈希表/字典实现,每个key对应一个WPF 资源对象属性,其部分属性和方法如下:
属性 | 说 明 |
---|---|
[键] | 获取或设置与给定键相关联的值。 |
Count | 获取资源的个数。 |
Keys | 获取字典中所有键的集合。 |
Values | 获取字典中包含的所有键对应的所有值的集合。 |
MergedDictionaries | 获取 ResourceDictionary 字典的集合,这些字典构成了合并字典中的各种资源字典。 |
Source | 资源字典XAML文件的路径。 |
方法 | 说 明 |
Add(Object, Object) | 将键、值 对添加到此字典中。 |
Contains(Object) | 字典中是否包含带有指定键的元素 。 |
Remove(Object) | 从字典中移除带有指定键的项 。 |
在 WPF中使用资源,需要使用 StaticResource 或者DynamicResource 标记使用资源。StaticResource 在编译时即确定值,而 DynamicResource 则表示资源在运行时动态计算值。
<Window.Resources>
<sys:String x:Key="MyString">我是张三</sys:String>
<SolidColorBrush x:Key="MyBrush" Color ="red" ></SolidColorBrush>
<BitmapImage x:Key="MyImage" UriSource = "Images/ball.jpg"></BitmapImage>
</Window.Resources>
<Grid>
<Label x:Name="label" Content="{StaticResource MyString}" Height="40" Width="80" Margin="146,53,574,342" />
<Label x:Name="label1" Content="{DynamicResource MyString}" Height="40" Width="80" Margin="146,118,574,277" />
<Label x:Name="label2" Content="{StaticResource MyString}" Background="{StaticResource MyBrush }" Height="40" Width="80" Margin="146,197,574,198" />
<Button x:Name="button" Content="Button" Click="button Click" Height="40" Width="80" Margin="146,291,574,104" />
<Image x:Name="image" Source="{DynamicResource MyImage}" Height="240" Width="240" Margin="400,97,160,98" />
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
//查找资源
SolidColorBrush s = (SolidColorBrush)FindResource("MyBrush");
//遍历资源
foreach (String k in Resources.Keys)
{
Console.WriteLine(k + "->" + Resources[k]);
}
//DynamicResource在运行期间会更新资源,StaticResource只在初始化时获取一次资源
//改变资源字典的值
Resources["MyString"] = "我的文字被改变啦";
Resources["MyImage"] = new BitmapImage(new Uri("/Images/cat.bmp", UriKind.Relative));
//Resources["MyImage"] = new BitmapImage(new Uri("pack://application:,,,/Images/cat.bmp"));
}
}
二、WPF资源范围
WPF资源可以放在以下范围,在使用使按照就近原则(顺序为元素集>页面级>应用级):
范围 | 说明 |
---|---|
元素级 | 这些资源仅在定义它们的元素内部可见,并且对外部元素不可用。 注意每一个框架级元素(继承自FrameworkElement)都有一个Resources资源属性。 |
页面级 | 资源定义在 <Window.Resources> 、<Page.Resources> 标记中这些资源只能被该页面中的元素访问。 Window类、Page类也是继承自FrameworkElement 。 |
应用程序级 | 定义在 App.xaml 文件中的 <Application.Resources> 标记中,在整个应用程序中都可以访问这些资源。 |
三、WPF资源词典
将不同类型的资源(如样式、模板、数据绑定)分别保存到不同的XAML文件中,使得代码更加清晰和易于维护,具有高重用性,这种文件我们称之为资源词典。
通过对项目右键→添加→新建项→资源词典,创建Dictionary1.xaml文件存储画刷、Dictionary2.xaml文件存储图片
在 XAML 中可以使用 < ResourceDictonary > 作为根元素来定义资源字典文件,其中Dictionary1.xaml与Dictionary2.xaml添加资源,并在app.xaml中进行资源合并。
Dictionary1.xaml内代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--画刷资源-->
<SolidColorBrush x:Key="MyBrush" Color="red"/>
<SolidColorBrush x:Key="MyBrush2" Color="Green"/>
<SolidColorBrush x:Key="MyBrush3" Color="Blue"/>
</ResourceDictionary>
Dictionary2.xaml内代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--图片资源-->
<BitmapImage x:Key="MyImage1" UriSource="Images/ball.jpg" />
<BitmapImage x:Key="MyImage2" UriSource="Images/cat.bmp" />
<BitmapImage x:Key="MyImage3" UriSource="Images/plane.png" />
</ResourceDictionary>
app.xaml内代码
<Application.Resources>
<ResourceDictionary>
<!--在此处定义的MyBrush顺序优于Dictionary1.xaml内的画刷-->
<SolidColorBrush x:Key="MyBrush" Color="Cyan"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
<ResourceDictionary Source="Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
MainWindow.xaml内代码
<Grid>
<Label x:Name="label" Content="Label" Background="{DynamicResource MyBrush}" HorizontalAlignment="Left" Margin="83,57,0,0" VerticalAlignment="Top" Height="73" Width="204" FontSize="24"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="83,217,0,0" VerticalAlignment="Top" Height="70" Width="204" Click="button_Click"/>
<Image x:Name="iamge" Source="{DynamicResource MyImage1}" HorizontalAlignment="Left" Height="244" Margin="400,57,0,0" VerticalAlignment="Top" Width="306"/>
</Grid>
MainWindow.xaml.cs内代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e) {
//获取app对象的资源字典属性
Application.Current.Resources["MyBrush"] = new SolidColorBrush(Colors.Purple);
//第二个资源字典文件
ResourceDictionary rd = Application.Current.Resources.MergedDictionaries[1];
rd["MyImage1"] = new BitmapImage(new Uri("pack://application:,,,/Images/cat.bmp"));
}
}
总结
- StaticResource 在编译时即确定值,而 DynamicResource 则表示资源在运行时动态计算值
- WPF资源访问使按照就近原则(顺序为元素集>页面级>应用级)
- WPF资源词典查找顺序由内向外,先查找自己的key-value值,若未找到再去MergedDictionaries中继续查找