原文: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. js进阶正则表达式实现过滤字符串(RegExp对象操作正则表达式)(正则:regular)(表达式:expression)

    js进阶正则表达式实现过滤字符串(RegExp对象操作正则表达式)(正则:regular)(表达式:expression) 一.总结 1.str_replace:正则作用:高效快速匹配 2.break ...

  2. jquery获取选中select的文本,值等

    jquery获取select选择的文本与值获取select :获取select 选中的 text :    $("#ddlregtype").find("option:s ...

  3. javascript数组全排列,数组元素所有组合

    function permute(input) { var permArr = [], usedChars = []; function main(input){ var i, ch; for (i ...

  4. before/after伪类常见用法

    1.清除浮动 ; } /*IE6/IE7*/ .clearfix:after{ display: block; content: "clear"; ; clear: both; o ...

  5. TortoiseGit拉取或推送项目提示 HTTP Basic: Access denied fatal: Authentication failed.

      TortoiseGit拉取或推送项目提示 HTTP Basic: Access denied fatal: Authentication failed. 大体意思是,HTTP基本认证失败,访问被拒 ...

  6. USB 3.0规范中译本 第5章 机械结构

    本文为CoryXie原创译文,转载及有任何问题请联系cory.xie#gmail.com. 本章定义USB 3.0连接器和线缆组件的form, fit 和 function.包括以下方面: • 连接器 ...

  7. http://lists.mysql.com/mysql

    http://lists.mysql.com/mysql http://www.ehowstuff.com/how-to-fix-mysql-database-error-cant-create-da ...

  8. 在nginx中使用lua直接訪问mysql和memcaced达到数据接口的统一

    安装nginx參见<nginx+lua+redis构建高并发应用> 让nginx 中的nginx_lua_module支持mysql 和memcache 下载 https://github ...

  9. 【b094&&z14】靶形数独

    [问题描述] 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的分们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向Z博士请教,Z博士拿出了他最近发明的&qu ...

  10. 三天打渔,俩天晒网(C++实现)

    #include <iostream> using namespace std; int leap (int a) {     if (a%4==0%a%100!=0||a%400==0) ...