WPF之动态换肤

简介: 原文:WPF之动态换肤如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式、窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果;对于简单的换肤操作,如更改背景颜色、设置窗体透明度,这种换肤操作,我们就不能使用上面的方法了,这个时候,我们只要在一个全局对象中添加几个属性,如背景颜色、前景颜色、窗体透明度等,然后,再绑定这几个属性就能达到我们想要的效果。
原文: WPF之动态换肤

如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式、窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果;对于简单的换肤操作,如更改背景颜色、设置窗体透明度,这种换肤操作,我们就不能使用上面的方法了,这个时候,我们只要在一个全局对象中添加几个属性,如背景颜色、前景颜色、窗体透明度等,然后,再绑定这几个属性就能达到我们想要的效果。

 

解决方案:动态加载资源字典

 1 <Window x:Class="DynamicallySkinnable.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Window.Resources>
 6     </Window.Resources>
 7     <Grid>
 8         <StackPanel Margin="20" Orientation="Vertical">
 9             <TextBox x:Name="tb"
10                        HorizontalAlignment="Center" VerticalAlignment="Center"
11                        Text="测试用例"></TextBox>          
12             <Button Content="Click Me"
13                     Click="Button_Click">
14                 <Button.ContextMenu>
15                     <ContextMenu>
16                         <MenuItem x:Name="menuBlue" Header="Blue Skin" Click="menuAero_Click"/>
17                         <MenuItem x:Name="menuRoyale" Header="Red Skin" Click="menuRoyale_Click"/>
18                         <MenuItem x:Name="menuLuna" Header="Black Skin" Click="menuLuna_Click"/>
19                     </ContextMenu>
20                 </Button.ContextMenu>
21             </Button>
22 
23         </StackPanel>
24     </Grid>
25 </Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DynamicallySkinnable
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)e.OriginalSource;
            btn.ContextMenu.IsOpen = true;
        }

        private void menuAero_Click(object sender, RoutedEventArgs e)
        {
            /*
            Application.Current.Resources.MergedDictionaries.Clear();   //清除现有资源

            //获取要应用的资源字典
            ResourceDictionary resource =
                (ResourceDictionary)Application.LoadComponent(
                    new Uri("/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/aero.normalcolor.xaml", UriKind.Relative));
            //将资源字典合并到当前资源中
            Application.Current.Resources.MergedDictionaries.Add(resource);
             */


            //this.Resources.MergedDictionaries.Clear();
            ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(new Uri("/DynamicallySkinnable;component/Skins/BlueSkin.xaml", UriKind.Relative));
            this.Resources.MergedDictionaries.Add(resource);
        }

        private void menuRoyale_Click(object sender, RoutedEventArgs e)
        {


            /*
            Application.Current.Resources.MergedDictionaries.Clear();
            ResourceDictionary resource =
                (ResourceDictionary)Application.LoadComponent(
                    new Uri("/PresentationFramework.Royale, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/royale.normalcolor.xaml", UriKind.Relative));
            Application.Current.Resources.MergedDictionaries.Add(resource);
             */


            //this.Resources.MergedDictionaries.Clear();
            ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(new Uri("/DynamicallySkinnable;component/Skins/RedSkin.xaml", UriKind.Relative));
            this.Resources.MergedDictionaries.Add(resource);
           
        }

        private void menuLuna_Click(object sender, RoutedEventArgs e)
        {
            /*
            Application.Current.Resources.MergedDictionaries.Clear();

            ResourceDictionary resource =
                (ResourceDictionary)Application.LoadComponent(
                    new Uri("/PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/luna.normalcolor.xaml", UriKind.Relative));
            Application.Current.Resources.MergedDictionaries.Add(resource);
             */


            //this.Resources.MergedDictionaries.Clear();
            ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(new Uri("/DynamicallySkinnable;component/Skins/BlackSkin.xaml", UriKind.Relative));
            this.Resources.MergedDictionaries.Add(resource);
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)e.OriginalSource;
            btn.ContextMenu.IsOpen = true;
        }
    }
}

 

后记:

  动态换肤在程序里面已经基本实现,主要是资源字典的动态加载,以及背景图片的替换,在Grid.Background的ImageBrush属性里面,在点击按钮之后更换了资源字典之后还是需要手动写代码替换一下背景的

写的时候就在想能不能写成属性通知的那个样子,当它发生改变了,自动去更新,不用我手动的去写代码,但是有种无从下手的感觉。

  这段时间老是会觉得自己的知识不够,遇到问题不能从本质上去了解及解决,一定要在网上荡代码参考怎么样的,实用主义,有的时候是好,但是后期的积累问题会越来越难以解决,所以要注意夯实基础,这段时间

需要好好的看一看基础的组成什么的。感觉自己什么都很匮乏。代码写的不够优雅,自己看着都觉得凌乱,变量名不优美,看着不赏心悦目。这些都是我的目标,现在方向有了。向着我的程序员之路,fighting!

目录
相关文章
|
C# 数据格式 XML
WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)
原文:WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树) 一、WPF对象级(Window对象)资源的定义与查找 实例一: StaticR...
8054 0
|
9月前
|
移动开发 开发框架 网络协议
WPF+ASP.NET SignalR实现动态折线图
WPF+ASP.NET SignalR实现动态折线图
83 0
|
IDE 编译器 C#
WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题。本文就探讨一下如何在WPF中实现一种基于行字段的动态公式计算。
991 0
WPF实现强大的动态公式计算
|
C# Windows
一起谈.NET技术,WPF 动态模拟CPU 使用率曲线图
在工作中经常会遇到需要将一组数据绘制成曲线图的情况,最简单的方法是将数据导入Excel,然后使用绘图功能手动生成曲线图。但是如果基础数据频繁更改,则手动创建图形可能会变得枯燥乏味。本篇将利用DynamicDataDisplay  在WPF 中动态模拟CPU 使用率图表,实现动态生成曲线图。
1999 0
|
C# Windows
WPF 定时器DispatcherTimer+GetCursorPos 的使用,动态查看屏幕上任一点坐标
原文:WPF 定时器DispatcherTimer+GetCursorPos 的使用,动态查看屏幕上任一点坐标 using System;using System.Collections.Generic;using System.
1021 0
|
C#
WPF 仪表盘 刻度盘 动态 加载中 开源
原文:WPF 仪表盘 刻度盘 动态 加载中 开源  1. 表盘   参数可以设置, codeproject上写的。网址在这里。 源码里有demo,很详细。 源码在这里。 2. 动态Loading  截图效果跟实际有点不一样。
1623 0
|
C# Windows
WPF 4 动态覆盖图标(Dynamic Overlay Icon)
原文:WPF 4 动态覆盖图标(Dynamic Overlay Icon)      在《WPF 4 开发Windows 7 任务栏》一文中我们学习了任务栏的相关开发内容,同时也对覆盖图标(Overlay Icon)功能进行了一些介绍,其中覆盖图标是以静态方式呈现的。
1089 0
|
C#
WPF通过代码动态的加载样式
原文:WPF通过代码动态的加载样式 tabitem.SetResourceReference(TabItem.StyleProperty, "mainTabItemStyle"); tabitem.Content = new Goods.GoodsMain();
1171 0
|
C# 存储
WPF 动态模拟CPU 使用率曲线图
原文:WPF 动态模拟CPU 使用率曲线图      在工作中经常会遇到需要将一组数据绘制成曲线图的情况,最简单的方法是将数据导入Excel,然后使用绘图功能手动生成曲线图。但是如果基础数据频繁更改,则手动创建图形可能会变得枯燥乏味。
1005 0
|
C#
WPF 动态更换样式文件
原文:WPF 动态更换样式文件   ApplySkinFromMenuItem("Style/BigImgStyle.xaml", "Style/FileListStyle.xaml");     //换肤        void ApplySkinFromMenuItem(string sou...
933 0