zoukankan      html  css  js  c++  java
  • WPF教程九:理解WPF中的对象资源

      在WPF中,所有继承自FrameworkElement的元素都包含一个Resources属性,这个属性就是我们这篇要讲的资源。

      这一篇讲解的资源是不是上一篇的程序集资源(那个是在编译过程中打包到程序集中),这个是资源是我们想在公共的地方写一个对象让其他元素重复使用。

      先贴个例子:

    <Window x:Class="NETResource.MainWindow"
            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:NETResource"0
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Window.Resources>
            <SolidColorBrush x:Key="RedBrushButtonBackground" Color="Red" />
        </Window.Resources>
        <Grid>
            <Grid.Resources>
                <SolidColorBrush x:Key="BlueBrushButtonBackground" Color="Blue"/>
            </Grid.Resources>
            <StackPanel>
                <Button Width="120" Background="{StaticResource RedBrushButtonBackground}" Content="我是按钮A"/>
                <Button Width="120" Background="{StaticResource BlueBrushButtonBackground}" Content="我是按钮B"/>
            </StackPanel>
        </Grid>
    </Window>

    显示效果: 

    从例子中我们看几个资源的关键点,我们再Window元素和Grid元素下添加两个颜色画刷资源,使用x:key标识。上面2个Button都使用了2个不同层级的父元素资源。WPF中有个设计比较好的地方就是元素可以使用父元素的资源。这样我们都把资源放在Window节点下,公用这些资源。

    资源定义好之后,再使用时,可以指定以静态的方式使用资源,还是以动态的方式使用资源。

    差别就是静态资源只从资源集合获取对象一次,对象的任何变化都会得到消息,而动态资源每次需要用到对象时都会重新从资源集合中查找对象。注意动态资源是每次需要用到对象时才会去资源集合查找,所以在资源非常大,且非常复杂的时候,可以用动态资源的方式可以提高第一次加载窗口的速度(因为没有解析资源标记的过程),其他任何使用都不建议使用动态资源。使用数据绑定去实现。

    <Window x:Class="NETResource.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:NETResource"
            mc:Ignorable="d"
            Title="Window1" Height="450" Width="800">
        <Window.Resources>
            <SolidColorBrush x:Key="ButtonBrushBackground" Color="DarkBlue"/>
        </Window.Resources>
        <Grid> 
            <StackPanel Width="120">
                <Button Content="按钮A静态资源" Background="{StaticResource ButtonBrushBackground}"/>
                <Button Content="按钮B动态资源" Background="{DynamicResource ButtonBrushBackground}"/>
                <Button Content="点击切换资源对象" Click="SetButtonBackgroudButton_OnClicked"/>
                <Button Content="点击修改资源的值" Click="UpdataButtonBackgroundButton_OnClicked"/>
            </StackPanel>
        </Grid>
    </Window>
    using System.Windows;
    using System.Windows.Media;
    
    namespace NETResource
    {
        /// <summary>
        /// Window1.xaml 的交互逻辑
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
            private void SetButtonBackgroudButton_OnClicked(object sender, RoutedEventArgs e)
            {
                //修改资源指向的对象。只有动态资源会受到影响,因为动态资源每次使用值的时候,都会重新读取。静态资源不会,所以静态资源不受影响。
                //修改样式1
                SolidColorBrush brush = new SolidColorBrush(Colors.Red);
                brush.Opacity = 0.3;
                this.Resources["ButtonBrushBackground"] = brush;
                //修改样式2
                // LinearGradientBrush linear = new LinearGradientBrush(Colors.Red, Colors.Blue, 90.0);
                // this.Resources["ButtonBrushBackground"] = linear;
            }
    
            private void UpdataButtonBackgroundButton_OnClicked(object sender, RoutedEventArgs e)
            {
                //修改资源对象的值,资源没有改变,只是改变了资源的值,所以2个按钮都受到影响。
                var brush = this.Resources["ButtonBrushBackground"];
                if (brush is SolidColorBrush solidColorBrush)
                {
                    solidColorBrush.Color = Colors.LightBlue;
                }
            }
        }
    }

    如果有些资源是所有窗体都共享的,建议写在Application的.Resources下。

    <Application x:Class="NETResource.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:NETResource"
                 StartupUri="Window1.xaml">
        <Application.Resources>
            <SolidColorBrush x:Key="TitleBrush" Color="Red"/>
        </Application.Resources>
    </Application>
    <Window x:Class="NETResource.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:NETResource"
            mc:Ignorable="d" 
            Title="WPF教程九:理解WPF中的资源"  
            Height="450" Width="800">
        
        <Window.Resources>
            <SolidColorBrush x:Key="ButtonBrushBackground" Color="DarkBlue"/>
        </Window.Resources>
        <Grid>
            <TextBlock Text="WPF教程九:理解WPF中的资源"  Foreground="{StaticResource TitleBrush}"/>    
        </Grid>
    </Window>

    资源我们都会使用了,接下来需要归类整理我们的资源,使用资源字典:

    我们在工程上右键=》添加=》资源字典=》设置名字为AppBrushes.xaml=》保存

    添加代码如下:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:NETResource">
        <SolidColorBrush x:Key="DictionaryTitleBrush" Color="Beige"/>
    </ResourceDictionary>

    在App.xaml中添加对资源字典的使用:

    <Application x:Class="NETResource.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:NETResource"
                 StartupUri="Window1.xaml">
        <Application.Resources> 
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="AppBrushes.xaml"/>
                </ResourceDictionary.MergedDictionaries>
                <SolidColorBrush x:Key="TitleBrush" Color="Red"/>
            </ResourceDictionary>  
        </Application.Resources>
    </Application>

    这样资源字典就可以被访问了。

    我们创建一个button按钮使用资源字典内的样式

      <Button Content="使用资源字典下的画刷" Background="{StaticResource DictionaryTitleBrush}"/>

    跨程序集使用资源:这个对象资源跨程序集使用。

    一定要分清楚,什么是二进制资源(程序集资源持久化),什么是对象资源(公共部分重复使用的对象)。我们手动创建引用其他库的资源字典。

     在新建资源DLL的时候,我没有找到直接新建添加引用之后的类库,所以我用以下2种方法种的一种来创建程序集,我使用的是第一种:

    1)创建WPF程序,然后删除他下面的App.config、App.xaml、MainWindow.xaml 和Properties下的Rsources.resx、Settings.settings,工程右键=》属性=》应用程序=》输出类型=》类库。用于保留自动对PresentationCore、PresentationFramlework、WindowsBase的引用。

    2)添加类库程序,然后添加=》引用=》PresentationCore、PresentationFramlework、WindowsBase。这三个的引用。

    添加DLL完毕后,在窗体程序中添加对DLL库的引用。整个目录引用关系结构如下: 

     现在开始写代码,

    首先是ResourceLibrary库。这个是我们的资源库,里面存放我们的资源文件。目前是一个xaml的资源字典。需要我们新建出来。

    代码如下:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:ResourceLibrary">
        <SolidColorBrush x:Key="ReusableTitle" Color="Yellow"/>
    </ResourceDictionary>

    而后是引用的App,在App.xaml下添加跨程序集的资源字典(使用pack: URI): 

    <Application x:Class="WPFUsingResourceLib.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:WPFUsingResourceLib"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/ResourceLibrary;component/ReusableDictionary.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>

     在Window窗体中使用以添加引用的资源:

    <Window x:Class="WPFUsingResourceLib.MainWindow"
            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:WPFUsingResourceLib"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid> 
            <Button  VerticalAlignment="Top" HorizontalAlignment="Left" Width="180" Height="30" Content="我是跨程序集使用资源" Background="{StaticResource  ReusableTitle}"/>         
        </Grid>
    </Window>

    效果图如下:

    好啦,这一篇就写这么多把。主要是就是对象资源的使用,静态和动态资源的差别,跨程序集资源,元素可以使用父类资源。这篇主要是理解就行,后面会写软件,用于演示如何更好的使用这些内容。

    我创建了一个C#相关的交流群。用于分享学习资料和讨论问题。欢迎有兴趣的小伙伴:QQ群:542633085

  • 相关阅读:
    谈谈一些有趣的CSS题目(十四)-- 纯 CSS 方式实现 CSS 动画的暂停与播放!
    Oracle 12c CDB PDB
    sqlplus 调试存储过程
    Oracle 存储过程A
    %notfound的理解——oracle存储过程 .
    ORA-04091: table xxx is mutating, trigger/function may not see it
    JQuery Div scrollTop ScrollHeight
    JQuery JSON Servlet
    div 移动
    HTML 三角符号
  • 原文地址:https://www.cnblogs.com/duwenlong/p/14612070.html
Copyright © 2011-2022 走看看