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 的顶部要和头部视图的背景图的高度 ...
随机推荐
- hadoop的Namenode HA原理详解
为什么要Namenode HA? 1. NameNode High Availability即高可用. 2. NameNode 很重要,挂掉会导致存储停止服务,无法进行数据的读写,基于此NameNod ...
- 使用VMware WorkStation虚拟机软件安装CentOS 8
使用VMware WorkStation虚拟机软件安装CentOS 8 说明:本章我们使用的虚拟机软件是VMware WorkStation15.5 PRO,镜像包是CentOS-8.2.2004-x ...
- Codeforces Round #627 (Div. 3) F - Maximum White Subtree(深度优先搜索)
题意: n 个点 n - 1 条边的树,问每个点所在所有子树中白黑点数目的最大差. 思路: 白点先由下至上汇集,后由上至下分并. #include <bits/stdc++.h> usin ...
- G - Can you answer these queries? & N - 花神游历各国
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to us ...
- UVA442 矩阵链乘 Matrix Chain Multiplication
题意: 这道题也是在不改变原序列每个元素位置的前提下,看每个元素与他身边的两个元素那个先结合能得到最大的能量 题解: 很明显这是一道区间dp的题目,这道题要断环成链,这道题需要考虑在这个区间上某个元素 ...
- HDU - 3281 dp
题意: 给你b个球,m个楼层,你需要找到一个楼层数k,使得从小于k这个楼层上面扔下去球,而球不会碎.求在最糟糕的情况下你最多要尝试多少次 题解: dp[i][j]表示你有b个球,楼层总数为m,你找到那 ...
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- AtCoder Beginner Contest 179 E - Sequence Sum (模拟)
题意:\(f(x,m)\)表示\(x\ mod\ m\),\(A_{1}=1\),而\(A_{n+1}=f(A^{2}_{n},M)\),求\(\sum^{n}_{i=1}A_{i}\). 题解:多算 ...
- Codeforces Global Round 9 C. Element Extermination (思维,栈)
题意:有一个长度\(n\)的序列,如果\(a_{i}<a_{i+1}\),那么可以选择删除\(a_{i}\)或者\(a_{i+1}\),再继续操作,问是否能够将序列删到只剩一个元素. 题解:感觉 ...
- Linux-进程管理命令
目录 进程管理命令-ps(静态) 进程管理命令-top(动态) 什么是中断 管理进程状态 kill命令 killall命令 pkill命令 pidof 和 pgrep 补充 关于优先级PR和NI 后台 ...