c#winform主题实现的一个方法
winform的主题实现没有bs里面那么舒服,下面做了一个简单实现,记录一下。
1、一个接口,需要做主题的控件、窗体都要实现这个接口
/// <summary>
/// 使用主题的控件、窗体需要实现此接口
/// </summary>
public interface IThemeControl
{
ITheme ThisTheme { get; set; }
/// <summary>
/// 重置主题
/// </summary>
void ResetTheme();
}
2、一个主题接口
/// <summary>
/// 主题
/// </summary>
public interface ITheme
{
int Code { get; }
/// <summary>
/// 初始化
/// </summary>
void Init(); }
3、一个主题控制类
1 /// <summary>
2 /// 主题设置
3 /// </summary>
4 public class Theme
5 {
6 internal delegate void CheckedThemeEventHandle(ITheme theme);
7 /// <summary>
8 /// 改变主题事件
9 /// </summary>
10 static internal event CheckedThemeEventHandle CheckedThemeEvent;
11 static ITheme currentTheme;
12 /// <summary>
13 /// 当前主题
14 /// </summary>
15 internal static ITheme CurrentTheme
16 {
17 get { return currentTheme; }
18 set
19 {
20 if (value == null)
21 return;
22 currentTheme = value;
23 currentTheme.Init();
24 if (CheckedThemeEvent != null)
25 {
26 CheckedThemeEvent(value);
27 }
28 }
29 }
30 /// <summary>
31 /// 加载控件的主题
32 /// </summary>
33 /// <param name="control"></param>
34 internal static void LoadTheme(IThemeControl control)
35 {
36 control.ResetTheme();
37 }
38 }
4、添加一个窗体通用的主题接口
public interface IThemeBaseForm
{
/// <summary>
/// 基本窗体背景色
/// </summary>
Color BaseFormBackgroundColor { get; }
/// <summary>
/// 基本窗体文字颜色
/// </summary>
Color BaseFormForeColor { get; }
/// <summary>
/// 标题栏颜色
/// </summary>
Color BaseFormTitleColor { get; }
}
5、添加对应的窗体或控件的主题接口
窗体的样式接口(例子)
public interface IThemeFrmLock : IThemeBaseForm
{
Color FrmLock_TxtFillColor { get; }
Color FrmLock_TxtRectColor { get; }
Color FrmLock_TxtForeColor { get; }
Color FrmLock_btnFillColor { get; }
Color FrmLock_btnForeColor { get; }
Color FrmLock_btnRectColor { get; } }
控件的样式接口(例子)
public interface IThemeUCFileItem : ITheme
{
Color UCFileItem_BackgroundColor { get; }
Color UCFileItem_ForeColor { get; }
Color UCFileItem_BoxColor { get; }
Image UCFileItem_Img1 { get; }
Image UCFileItem_Img2 { get; }
Image UCFileItem_Img3 { get; }
Image UCFileItem_Img4 { get; }
Image UCFileItem_Img5 { get; }
}
我这里做一个深色一个浅色主题
深色的
/// <summary>
/// 深色
/// </summary>
public partial class Dark :
ITheme,
IThemeBaseForm,
IThemeFrmLock,
IThemeUCFileItem
{ public int Code { get { return 1; } }
/// <summary>
/// 基本窗体背景色
/// </summary>
public Color BaseFormBackgroundColor { get { return Color.FromArgb(37, 41, 59); } }
/// <summary>
/// 基本窗体文字颜色
/// </summary>
public Color BaseFormForeColor { get { return Color.White; } }
public Color BaseFormTitleColor { get { return Color.FromArgb(38, 45, 67); } } /// <summary>
/// 初始化操作
/// </summary>
public void Init()
{
//这里做一些修改主题时候的业务
}
#region 重写运算符
/// <summary>
/// 重写==
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static bool operator ==(Dark lhs, ITheme rhs)
{ if (lhs == null && rhs == null)
return true;
else
{
if (lhs != null && rhs != null)
{
if (lhs.Code == rhs.Code)
return true;
else
return false;
}
else
return false;
}
} /// <summary>
/// 重写!=
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
/// <returns></returns>
public static bool operator !=(Dark lhs, ITheme rhs)
{ if (lhs == null && rhs == null)
return false;
else
{
if (lhs != null && rhs != null)
{
if (lhs.Code == rhs.Code)
return false;
else
return true;
}
else
return true;
}
} public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
if (obj is ITheme)
{
if (Code == ((ITheme)obj).Code)
return true;
else
return false;
}
else
{
return false;
}
} public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion
}
浅色的也一样 只需要实现
ITheme,
IThemeBaseForm,
IThemeFrmLock,
IThemeUCFileItem
这些接口就行(定义的控件接口,这里都要进行实现)
然后添加具体的控件主题实现类
/// <summary>
/// FrmLock
/// </summary>
public partial class Dark
{
public Color FrmLock_TxtFillColor { get { return Color.FromArgb(34, 40, 60); } }
public Color FrmLock_TxtRectColor { get { return Color.FromArgb(65, 75, 101); } }
public Color FrmLock_TxtForeColor { get { return Color.White; } }
public Color FrmLock_btnFillColor { get { return Color.FromArgb(46, 54, 76); } }
public Color FrmLock_btnForeColor { get { return Color.FromArgb(175, 193, 225); } }
public Color FrmLock_btnRectColor { get { return Color.FromArgb(65, 75, 101); } }
}
然后就是去控件或窗体里面做事情了,实现接口Theme.IThemeControl,构造函数里面添加CheckedThemeEvent事件
public partial class FrmLock : FrmWithTitle,Theme.IThemeControl
{ public FrmLock()
{
try
{
InitializeComponent();
Theme.Theme.CheckedThemeEvent += Theme_CheckedThemeEvent;
}
catch (Exception ex)
{ }
}
void Theme_CheckedThemeEvent(Theme.ITheme theme)
{
if (this.Visible)
{
ThisTheme = theme;
}
}
VisibleChanged事件添加内容
private void FrmLock_VisibleChanged(object sender, EventArgs e)
{
if (Visible)
{
ThisTheme = Theme.Theme.CurrentTheme;
}
}
实现的接口
Theme.ITheme thisTheme = null;
/// <summary>
/// 当前页面正在使用的主题
/// </summary>
public Theme.ITheme ThisTheme
{
get
{
if (thisTheme == null)
{
ThisTheme = Theme.Theme.CurrentTheme;
}
return thisTheme;
}
set
{
if (thisTheme != value)
{
thisTheme = value;
Theme.Theme.LoadTheme(this);
}
}
} public void ResetTheme()
{
var t = (Theme.IThemeFrmLock)ThisTheme;
this.BackColor = t.BaseFormBackgroundColor;
this.lblTitle.BackColor = t.BaseFormTitleColor;
this.lblTitle.ForeColor = t.BaseFormForeColor; ucControlBase1.FillColor = t.FrmLock_TxtFillColor;
ucControlBase1.RectColor = t.FrmLock_TxtRectColor;
txtPW.BackColor = t.FrmLock_TxtFillColor;
txtPW.ForeColor = t.FrmLock_TxtForeColor;
tongyong_btnPaiZhaoPath.FillColor = t.FrmLock_btnFillColor;
tongyong_btnPaiZhaoPath.RectColor = t.FrmLock_btnRectColor;
tongyong_btnPaiZhaoPath.ForeColor = t.FrmLock_btnForeColor;
}
以上就是修改代码,下面看调用
Theme.Theme.CurrentTheme = new Theme.Dark();
效果

c#winform主题实现的一个方法的更多相关文章
- C# winform调用浏览器打开页面方法分享,希望对大家有帮助
在很多客户端程序中我们都需要调用浏览器打开网页,这里分享一个可以在我winform程序调用浏览器的方法,测试通过了. 声明:这个方法是上万个用户测试通过的,不是我没有测试通过就拿出来分享,那个是自己搬 ...
- 关于winform主题IrisSkin2的编写
第一步:首先引用IrisSkin2.dll. 第二步自定义类: /// <summary> /// 窗体主题边界类 /// </summary> public class Fo ...
- C#WinForm无边框窗体移动方法、模仿鼠标单击标题栏移动窗体位置
C#WinForm无边框窗体移动方法.模仿鼠标单击标题栏移动窗体位置 这里介绍俩种办法 方法一:直接通过修改窗体位置从而达到移动窗体的效果 方法二:直接伪装发送单击任务栏消息,让应用程序误以为单击任务 ...
- WinForm无边框窗体移动方法
C#WinForm无边框窗体移动方法.模仿鼠标单击标题栏移动窗体位置 这里介绍俩种办法 方法一:直接通过修改窗体位置从而达到移动窗体的效果 方法二:直接伪装发送单击任务栏消息,让应用程序误以为单击任务 ...
- 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n
35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...
- JavaScript中以一个方法作为参数的写法
前言,我们写js的时候,经常会看到一些方法,比如说: $("#ids").click(function( alert("Click me"); )); ---- ...
- 20款最佳用户体验的Sublime Text 2/3主题下载及安装方法
20款最佳用户体验的Sublime Text 2/3主题下载及安装方法
- ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”
ERROR: “System.Web.Mvc.Controller.File(string, string, string)”是一个“方法”,这在给定的上下文中无效 这是一个与Controller.F ...
- iOS之下拉放大,上推缩小,一个方法搞定
先来看看效果吧. 讲讲大概的实现思路:1、创建头部的视图和tableview,需要注意的是tableview要设置contentInset,contentInsent 的顶部要和头部视图的背景图的高度 ...
随机推荐
- 给jekyll博客添加天气插件
layout: post title: 给博客添加天气插件 date: 2020-04-26 author: Dapenson header-img: img/post-bg-debug.png ca ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链
JavaScript 原型和原型链 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 本篇文章旨在为 JavaScript继承 打下基础 原型 在 ...
- 动态规划TG.lv(1) (洛谷提高历练地)
动态规划TG.lv(1) P1005 矩阵取数游戏 分析:每行不超过80个数字,直接区间DP即可,\(dp[i][j]\)表示区间\([i,j]\)之间取数可以得到的答案,每次向右或者向左扩展即可.但 ...
- Codeforces Round #637 (Div. 2)
比赛链接:https://codeforces.com/contest/1341 A - Nastya and Rice 题意 有 n 堆米,每堆质量在 [a-b,a+b] 之间,这些米的总质量是否可 ...
- 【uva 1349】Optimal Bus Route Design(图论--网络流 二分图的最小权完美匹配)
题意:有一个N个点的有向带权图,要求找若干个有向圈,使得每个点恰好属于一个圈.请输出满足以上条件的最小权和. 解法:有向圈?也就是每个点有唯一的后继.这是一个可逆命题,同样地,只要每个点都有唯一的后继 ...
- Codeforces Round #654 (Div. 2) B. Magical Calendar (结论)
题意:你需要在长度从\(1\)~\(k\),宽度无限的网格图中造图形(每个点四周必须连通),问最多能造出多少种不同的图形. 题解:感觉没什么好说的,就是画图找规律,如果\(r\ge n\)的话(即没有 ...
- Linux core dump使用
什么是 core dump? core dump是一个当进程意外终止时包含进程内存内容的文件.当程序崩溃的时候,core dump由kernel触发.core dump可以作为程序崩溃时的事后快照(p ...
- Vue的七种传值方式
目录 1,父传子 2,子传父 3,兄弟组件传值 4,父组件使用子组件的数据和方法 5,子组件使用父组件的数据和方法 6,Vuex传值 6.1,定义store 6.2,挂载 6.3,使用 7,路由传值 ...
- TextCNN论文解读
引言 本文是对<Convolutional Neural Networks for Sentence Classification>的原理解读,简称TextCNN. 作者提出了一种基于CN ...
- leetcode17 电话号码的字母组合 dfs
就dfs吧.... 然后,我傻了.前一道题不用考虑空,这道题就要考虑.... 还有注意vector要引用传递 class Solution { public: void dfs(string temp ...