原文:WPF之动态换肤

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

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

 <Window x:Class="DynamicallySkinnable.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
</Window.Resources>
<Grid>
<StackPanel Margin="20" Orientation="Vertical">
<TextBox x:Name="tb"
HorizontalAlignment="Center" VerticalAlignment="Center"
Text="测试用例"></TextBox>
<Button Content="Click Me"
Click="Button_Click">
<Button.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuBlue" Header="Blue Skin" Click="menuAero_Click"/>
<MenuItem x:Name="menuRoyale" Header="Red Skin" Click="menuRoyale_Click"/>
<MenuItem x:Name="menuLuna" Header="Black Skin" Click="menuLuna_Click"/>
</ContextMenu>
</Button.ContextMenu>
</Button> </StackPanel>
</Grid>
</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!

WPF之动态换肤的更多相关文章

  1. hybird之web动态换肤实现

    前言 最近在重构个hybird(原生的壳包着Web页面)的UI框架,进行到了做换肤功能的阶段,所以这里是我思考的解决的方法. 预想 目前实现换肤的功能无非就两种做法. 1.写几个皮肤文件,然后切换使用 ...

  2. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

  3. duilib入门之贴图描述、类html文本描述、动态换肤、Dll插件、资源打包

    转载自duilib入门文档 贴图描述: Duilib的表现力丰富很大程度上得益于贴图描述的简单强大.Duilib的贴图描述分为简单模式和复杂模式两种. 简单模式使用文件名做为贴图描述内容,在这种方式下 ...

  4. Cocos2d-x 3.0 cocostudio骨骼动画的动态换肤

    概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现.在接下来的这个Demo ...

  5. Android动态换肤(二、apk免安装插件方式)

    在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...

  6. Android动态换肤(一、应用内置多套皮肤)

    动态换肤在很多android应用中都有使用,用户根据自己的喜好设置皮肤主题,可以增强用户使用应用的舒适度. Android换肤可以分为很多种,它们从使用方式,用户体验以及项目框架设计上体现了明显的差异 ...

  7. element-ui 动态换肤

    1.在安装好 element-ui@2.x 以后,首先安装sass-loader npm i sass-loader node-sass -D 2.安装 element-theme npm i ele ...

  8. 【WPF】实现动态切换语言(国际化)以及动态换肤功能

    前言:以下内容,手把手从搭建到最终实现,完成多语言切换以及换装功能. 本地系统环境:win 10 编译器环境:VS2022 社区版 .NET 环境: .NET 6 1.新建一个WPF项目 2.新建完毕 ...

  9. vue+ element 动态换肤

    转至 https://www.cnblogs.com/dengqichang/p/10364455.html 一.搭建好项目的环境. 二.根据ElementUI官网的自定义主题(http://elem ...

随机推荐

  1. IIS服务器能支持10万并发

    服务器能支持10万并发由于一个项目的访问量越来越大,从原来的几百个,增加到现在50多万个每天,所以阿里的服务器也扛不住了,于是就想办法,查了N多资料,总结了以下方法,才解决这问题,每天一共访问量50多 ...

  2. 搭建基于java环境

    .net项目架构改造之搭建基于java环境配置一览[上]   最近公司做了一个项目,需要嵌套在千牛的客户端上,项目代码必须上阿里的聚石塔,全程采用基于docker的自动化部署,我们的项目是基于.net ...

  3. ccpc2016长春站打铁记(后记)

    Day3 "学术交流日" 自己进我的空间看吧. http://user.qzone.qq.com/190741511/4

  4. Shuttle ESB(三)——架构模型介绍(2)

    上一篇文章中,介绍了Shuttle ESB架构模型中的三个重要部分. 今天,我们继续介绍剩余的三个内容:模式和消息路由. 四.模式 Request/Response(请求/响应模式) 对基于Reque ...

  5. PHP移动互联网开发笔记(4)——自定义函数及数组

    一.自定义函数 自定义函数就是我们自己定义的函数,在PHP中自定义函数格式如下: function funname(arg1, arg2, arg3......){ //TODO return val ...

  6. linux桥接模式下配置静态ip

    原文链接:http://blog.csdn.net/qq_37936542/article/details/79494993 一:桥接模式 VMware桥接模式,也就是将虚拟机的虚拟网络适配器与主机的 ...

  7. SpringMVC拦截器-路径语法-略坑

    项目中遇到一种场景,登录拦截器需要拦截.html后缀等动态请求,但是发现语法不对头.    <mvc:interceptors>      <mvc:interceptor> ...

  8. ios tableView那些事

    iOS开发很重要的一个功能就是tableView,可以说熟练使用tableView是iOS开发必修的课程,网上很多相关介绍,推荐一个博客参考一下: http://blog.csdn.net/lengs ...

  9. JVM调优之Tomcat启动参数配置及详解

    开发项目中会遇到Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的问题,通过查找资料找到是通过设置Tomcat 启动堆空间大小.年轻代大小.每 ...

  10. 不要完全相信Chrome控制台打印的信息

    以下两张图,第一张是Chrome控制台Network里请求返回的信息,图二是在代码里在请求返回的处理第一行代码用console.log打印的信息. 图一 图二 那么问题来了,为何通过console.l ...