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();
效果