WPF资源
1.资源的定义
每个框架级元素都具有 Resources 属性,该属性是包含已定义资源的 ResourceDictionary 类型, 支持索引,而且查询资源的时候,会先从本控件开始找,然后一层层向上,最后会到达Application的资源。

你可以在任何元素上定义资源,例如 Ellipse。 但是,最常在根元素上定义资源,如Window。
1.1 窗体和控件资源
<!--窗体资源-->
    <Window.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
    </Window.Resources>
    <DockPanel>
        <!--静态资源-->
        <Ellipse Fill="{StaticResource MyBrush}" Width="100" Height="100"/>
        <!--动态资源-->
        <Ellipse Fill="{DynamicResource MyBrush}" Width="100" Height="100"/>
        <!--控件中的资源,注意引用动态资源,否则不作用-->
        <Ellipse x:Name="Ellipse1" Width="100" Height="100" Fill="{DynamicResource MyBrush}">
            <Ellipse.Resources>
                <SolidColorBrush x:Key="MyBrush" Color="Red"/>
            </Ellipse.Resources>
        </Ellipse>
    </DockPanel>
1.2 应用程序资源
如果在控件或其他容器中知道包含窗口或页面找不到指定的资源,WPF会继续查找为应用程序定义的资源。在Visual Studio中,这些资源在App.xaml文件的标记中定义的资源。 
<Application x:Class="WpfApp2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp2"
             StartupUri="Window1.xaml">
    <Application.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
    </Application.Resources>
</Application>
1.3 框架中的资源
- SystemColors:访问系统颜色设置。
 - SystemFonts:访问字体设置。
 - SystemParamerers:封装了大量的设置列表,这些设置描述了各种屏幕像素的标准尺寸、键盘和鼠标设置、屏幕尺寸以及各种图形效果(如热跟踪、阴影以及拖动窗口时显示窗口内容)是否已经打开。
 
2.静态和动态资源
静态资源使用(StaticResource)指的是在程序载入内存时对资源的一次性使用,之后就不再去访问这个资源了;
动态资源使用(DynamicResource)指的是在程序运行过程中仍然会去访问资源。
例如:
public Window1()
{
    InitializeComponent();
    this.Resources["MyBrush"] = new SolidColorBrush(Colors.Green);           
}
执行如上代码,对于静态资源没影响,动态资源会发生变化。
--------->
访问资源:可以使用TryFindResource()代替FindResource()。如果找不到资源会返回null,而不是抛异常。
//查找Ellipse1的资源,但不会改变控件资源
var brush = (SolidColorBrush)Ellipse1.FindResource("MyBrush");
3.资源字典
资源字典只是xaml文档,除了存储希望使用的资源外,不做其他任何事情。ResourceDictionary具有Source属性,把包含资源定义的文件路径复制给这个属性即可。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="MyBrush" Color="Blue"/>
</ResourceDictionary>
程序集间共享资源,可将资源字典整合到App.xaml应用程序资源中。
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--将以下的资源字典 归并道app.xaml 字典中一起编译成baml-->
            <!--务必将app.xaml和以下的资源字典都设置成生成操作 bulid action-->
            <ResourceDictionary Source="Dictionary1.xaml"></ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
在窗口的Window.Resources中用。
<Window.Resources>
    <ResourceDictionary Source="Dictionary1.xaml"/>
</Window.Resources>
4. 资源合并
(1)创建
首先是共享资源的创建,创建一个新的“WPF自定义控件”项目。

资源字典文件(Dictionary1.xaml):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:CustomControl1},ResourceId=MyBrush}"  
        Color="Blue"/>
</ResourceDictionary>
若使用到图片等资源,要是用绝对 Pack URI 路径,并将“生成操作”设置为“资源”。
Pack URI 固定格式:
pack://application,,,[/程序集名称;][可选版本号;][文件夹名称/]文件名称
“//application,,,”可以省略,“/程序集名称,可选版本号”可以使用缺省值
在使用Pack URI路径时有几点需要注意:
- Pack URI使用从右向左的正斜线(/)表示路径。
 - 使用缩略写法意味着是相对路径,C#代码中的UriKind必须为Relative而且代表根目录的/可以省略。
 - 使用完整写法时是绝对路径,C#代码中的UriKind必须为Absolute并且代表根目录的/不能省略。
 - 使用相对路径时可以借助类似DOS的语法进行导航,比如./代表同级目录、…/代表父级目录。
 
(2)资源配置
如果你创建了多个资源字典作为共享资源的话,进行资源合并就是必须的,资源合并的代码写在Generic.xaml里:
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ResourceLib">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/ResourceLib;component/Dictionary1.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
与Pack URI等价的C#代码:
Uri uri=new Uri(@"./Dictionary1.xaml",UriKind.Relative);//相对路径使用
Uri uri=new Uri(@"pack://application:,,,/ResourceLib;component/Dictionary1.xaml",UriKind.Absolute);//绝对路径使用
CustomControl1 类文件:
public class CustomControl1 : Control
{
    public static ComponentResourceKey MyBrush
    {
        get
        {
            return new ComponentResourceKey(typeof(CustomControl1), "MyBrush");
        }
    }
}
(3) 编译生成 组件“ResourceLib.dll”,在新项目中引用。
(4)xaml 命名空间引入ResourceLib,并使用。
<Window x:Class="WpfApp2.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        xmlns:res="clr-namespace:ResourceLib;assembly=ResourceLib"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">
    <DockPanel>
        <!--res:CustomControl1.test 是ComponentResourceKey,必须使用 DynamicResource-->
        <Ellipse Fill="{DynamicResource {x:Static res:CustomControl1.MyBrush}}" Width="100" Height="100"/>
    </DockPanel>
</Window>
                    
                
                
            
        
浙公网安备 33010602011771号