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 的顶部要和头部视图的背景图的高度 ...
随机推荐
- python中字符串的翻转(方法总结)
Python翻转字符串(reverse string), 一共包含5种方法, 其中第一种最简单, 即步长为-1, 输出字符串; 方法如下 5种方法的比较: 1. 简单的步长为-1, 即字符串的翻转(常 ...
- 一块网卡配2IP地址
我们知道在Linux下网卡被称为eth0,eth1,eth2.....,所有网卡的配置文件都存储在 /etc/sysconfig/network-script/下,文件名是以ifcfg-eth0,if ...
- 对项目版本自动控制——利用gitversion
对项目版本自动控制--利用gitversion 目录 对项目版本自动控制--利用gitversion 1 为什么需要自动版本控制 2 如何使项目版本一目了然 3 Dot Net Core,程序集中的版 ...
- A - 欧拉回路
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个图,问是否存在欧拉回路? Input测试输入包含若干测试用例.每个测试用例的第1行给出两个正整数,分别是节点数N ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- FZU - 1901 Period II (kmp)
传送门:FZU - 1901 题意:给你个字符串,让你求有多少个p可以使S[i]==S[i+P] (0<=i<len-p-1). 题解:这个题是真的坑,一开始怎么都觉得自己不可能错,然后看 ...
- Codeforces Round #697 (Div. 3) D. Cleaning the Phone (思维,前缀和)
题意:你的手机有\(n\)个app,每个app的大小为\(a_i\),现在你的手机空间快满了,你需要删掉总共至少\(m\)体积的app,每个app在你心中的珍惜值是\(b_i\),\(b_i\)的取值 ...
- 【2020杭电多校】 Lead of Wisdom、The Oculus
题目链接:Lead of Wisdom 题意:有n个物品,这些物品有k种类型.每种物品有对应的类型ti,其他值ai,bi,ci,di 你可以选择一些物品,但是这些物品要保证它们任意两者之间类型不能相同 ...
- POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...
- JavaScript——DOMM
文本节点 != 文本内容