c#winform主題實現的一個方法

冰封一夏發表於2021-02-24

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

 

效果

 

 

 

相關文章