C# 轻松实现对窗体(Form)换肤[转]

    一直想写一个比较完整的、容易扩展的窗体换肤的方案,由于时间问题,都没去实现这个想法。现在有朋友提出需要,就把以前写的重新拿出来看了一篇,花了些时间,做出了现在的这个换肤的方案。实现的过程中遇到了不少问题,但还是解决了,虽然也许还有些缺陷,但也算是比较完善了。现在只实现了完全代码绘制的SkinFormProfessionalRenderer,接下来有时间会写一个SkinFormImageRenderer,实现只要做好图片就可以换肤。

在这先里发一下牢骚,最近看到很多网站转载了截图控件那几篇文章,但是版权声明、作者信息都去掉了,说实话,心里很不爽,这些文章和代码都是我辛辛苦苦的花了不少时间写出来的,我也没有不允许转载,但是你转载的时候为什么还要把作者信息去掉呢,请你尊重一下作者的劳动好吗?发完牢骚,先来看一下窗体换肤后的效果吧。

看完效果,来看看SkinForm的实现原理:

1、  把Form设置为无标题栏窗口。

2、  为了使Form可以像标准的Windows窗体那样拥有系统菜单和拖动改变窗体大小,加入WS_THICKFRAME和WS_SYSMENU窗体样式。

3、  处理相应得窗体消息,实现窗体的标准操作。

4、  实现SkinFormRenderer,绘制窗体的标题栏、边框、按钮等。

原理只做简单介绍,要详细说明,那得写很多东西了,介绍一下SkinForm中加入的几个属性的功能:

1、  BorderWidth,设置或获取窗体的边框的宽度。

2、  CanResize:设置或获取窗体是否可以改变大小。

3、  CaptionFont:设置或获取窗体标题的字体。

4、  CapntionHeight:设置或获取窗体标题栏的高度。

5、  CloseBoxSize:设置或获取关闭按钮的大小。

6、  MinimizeBoxSize:设置或获取最小化按钮的大小。

7、  MaximizeBoxSize:设置或获取最大化(还原)按钮的大小。

8、  ControlBoxOffset:设置或获取控制按钮的偏移。

9、  ControlBoxSpace:设置或获取控制按钮的间距。

10、 RoundStyle:设置或获取窗体的圆角样式。

11、   Radius:设置或获取窗体的圆角的大小。

12、   Renderer:设置或获取窗体的绘制方法。

接下来介绍窗体的绘制类SkinFormRenderer,这是比较重要的类,它是一个抽象类,重写它里面的绘制方法,就可以得到新的窗体皮肤。这个类里面主要有几个抽象方法:

1、  CreateRegion:创建一个Region,提供给SkinForm使用。

2、  OnRenderSkinFormCaption:绘制窗体标题栏。

3、  OnRenderSkinFormBorder:绘制窗体边框。

4、  OnRenderSkinFormBackground:绘制窗体背景。

5、  OnRenderSkinFormControlBox:绘制窗体控制按钮(最小化、最大化、关闭);

看看SkinFormRenderer的完整代码:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public abstract class SkinFormRenderer  
  2.   
  3.     {  
  4.  
  5.         #region Fields  
  6.   
  7.   
  8.   
  9.         private EventHandlerList _events;  
  10.   
  11.   
  12.   
  13.         private static readonly object EventRenderSkinFormCaption = new object();  
  14.   
  15.         private static readonly object EventRenderSkinFormBorder = new object();  
  16.   
  17.         private static readonly object EventRenderSkinFormBackground = new object();  
  18.   
  19.         private static readonly object EventRenderSkinFormControlBox = new object();  
  20.  
  21.  
  22.  
  23.         #endregion  
  24.  
  25.  
  26.  
  27.         #region Constructors  
  28.   
  29.   
  30.   
  31.         protected SkinFormRenderer()  
  32.   
  33.         {  
  34.   
  35.         }  
  36.  
  37.  
  38.  
  39.         #endregion  
  40.  
  41.  
  42.  
  43.         #region Properties  
  44.   
  45.   
  46.   
  47.         protected EventHandlerList Events  
  48.   
  49.         {  
  50.   
  51.             get  
  52.   
  53.             {  
  54.   
  55.                 if (_events == null)  
  56.   
  57.                 {  
  58.   
  59.                     _events = new EventHandlerList();  
  60.   
  61.                 }  
  62.   
  63.                 return _events;  
  64.   
  65.             }  
  66.   
  67.         }  
  68.  
  69.  
  70.  
  71.         #endregion  
  72.  
  73.  
  74.  
  75.         #region Events  
  76.   
  77.   
  78.   
  79.         public event SkinFormCaptionRenderEventHandler RenderSkinFormCaption  
  80.   
  81.         {  
  82.   
  83.             add { AddHandler(EventRenderSkinFormCaption, value); }  
  84.   
  85.             remove { RemoveHandler(EventRenderSkinFormCaption, value); }  
  86.   
  87.         }  
  88.   
  89.   
  90.   
  91.         public event SkinFormBorderRenderEventHandler RenderSkinFormBorder  
  92.   
  93.         {  
  94.   
  95.             add { AddHandler(EventRenderSkinFormBorder, value); }  
  96.   
  97.             remove { RemoveHandler(EventRenderSkinFormBorder, value); }  
  98.   
  99.         }  
  100.   
  101.   
  102.   
  103.         public event SkinFormBackgroundRenderEventHandler RenderSkinFormBackground  
  104.   
  105.         {  
  106.   
  107.             add { AddHandler(EventRenderSkinFormBackground, value); }  
  108.   
  109.             remove { RemoveHandler(EventRenderSkinFormBackground, value); }  
  110.   
  111.         }  
  112.   
  113.   
  114.   
  115.         public event SkinFormControlBoxRenderEventHandler RenderSkinFormControlBox  
  116.   
  117.         {  
  118.   
  119.             add { AddHandler(EventRenderSkinFormControlBox, value); }  
  120.   
  121.             remove { RemoveHandler(EventRenderSkinFormControlBox, value); }  
  122.   
  123.         }  
  124.  
  125.  
  126.  
  127.         #endregion  
  128.  
  129.  
  130.  
  131.         #region Public Methods  
  132.   
  133.   
  134.   
  135.         public abstract Region CreateRegion(SkinForm form);  
  136.   
  137.   
  138.   
  139.         public abstract void InitSkinForm(SkinForm  form);  
  140.   
  141.   
  142.   
  143.         public void DrawSkinFormCaption(  
  144.   
  145.             SkinFormCaptionRenderEventArgs e)  
  146.   
  147.         {  
  148.   
  149.             OnRenderSkinFormCaption(e);  
  150.   
  151.             SkinFormCaptionRenderEventHandler handle =  
  152.   
  153.                 Events[EventRenderSkinFormCaption]  
  154.   
  155.                 as SkinFormCaptionRenderEventHandler;  
  156.   
  157.             if (handle != null)  
  158.   
  159.             {  
  160.   
  161.                 handle(this, e);  
  162.   
  163.             }  
  164.   
  165.         }  
  166.   
  167.   
  168.   
  169.   
  170.   
  171.         public void DrawSkinFormBorder(  
  172.   
  173.             SkinFormBorderRenderEventArgs e)  
  174.   
  175.         {  
  176.   
  177.             OnRenderSkinFormBorder(e);  
  178.   
  179.             SkinFormBorderRenderEventHandler handle =  
  180.   
  181.                 Events[EventRenderSkinFormBorder]  
  182.   
  183.                 as SkinFormBorderRenderEventHandler;  
  184.   
  185.             if (handle != null)  
  186.   
  187.             {  
  188.   
  189.                 handle(this, e);  
  190.   
  191.             }  
  192.   
  193.         }  
  194.   
  195.   
  196.   
  197.   
  198.   
  199.         public void DrawSkinFormBackground(  
  200.   
  201.             SkinFormBackgroundRenderEventArgs e)  
  202.   
  203.         {  
  204.   
  205.             OnRenderSkinFormBackground(e);  
  206.   
  207.             SkinFormBackgroundRenderEventHandler handle =  
  208.   
  209.                 Events[EventRenderSkinFormBackground]   
  210.   
  211.                 as SkinFormBackgroundRenderEventHandler;  
  212.   
  213.             if (handle != null)  
  214.   
  215.             {  
  216.   
  217.                 handle(this, e);  
  218.   
  219.             }  
  220.   
  221.         }  
  222.   
  223.   
  224.   
  225.         public void DrawSkinFormControlBox(  
  226.   
  227.             SkinFormControlBoxRenderEventArgs e)  
  228.   
  229.         {  
  230.   
  231.             OnRenderSkinFormControlBox(e);  
  232.   
  233.             SkinFormControlBoxRenderEventHandler handle =  
  234.   
  235.                 Events[EventRenderSkinFormControlBox]  
  236.   
  237.                 as SkinFormControlBoxRenderEventHandler;  
  238.   
  239.             if (handle != null)  
  240.   
  241.             {  
  242.   
  243.                 handle(this, e);  
  244.   
  245.             }  
  246.   
  247.         }  
  248.  
  249.  
  250.  
  251.         #endregion  
  252.  
  253.  
  254.  
  255.         #region Protected Render Methods  
  256.   
  257.   
  258.   
  259.         protected abstract void OnRenderSkinFormCaption(  
  260.   
  261.             SkinFormCaptionRenderEventArgs e);  
  262.   
  263.   
  264.   
  265.         protected abstract void OnRenderSkinFormBorder(  
  266.   
  267.             SkinFormBorderRenderEventArgs e);  
  268.   
  269.   
  270.   
  271.         protected abstract void OnRenderSkinFormBackground(  
  272.   
  273.             SkinFormBackgroundRenderEventArgs e);  
  274.   
  275.   
  276.   
  277.         protected abstract void OnRenderSkinFormControlBox(  
  278.   
  279.             SkinFormControlBoxRenderEventArgs e);  
  280.  
  281.  
  282.  
  283.         #endregion  
  284.  
  285.  
  286.  
  287.         #region Protected Methods  
  288.   
  289.   
  290.   
  291.         [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]  
  292.   
  293.         protected void AddHandler(object key, Delegate value)  
  294.   
  295.         {  
  296.   
  297.             Events.AddHandler(key, value);  
  298.   
  299.         }  
  300.   
  301.   
  302.   
  303.         [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]  
  304.   
  305.         protected void RemoveHandler(object key, Delegate value)  
  306.   
  307.         {  
  308.   
  309.             Events.RemoveHandler(key, value);  
  310.   
  311.         }  
  312.  
  313.  
  314.  
  315.         #endregion  
  316.   
  317.     }  

在项目中实现了SkinFormProfessionalRenderer类,这个类实现了类似QQ2008的窗体的绘制,效果就是文章开始那贴出来的图了。还有一些其他辅助功能的类就不一一介绍了,接下来有时间,我会实现一个SkinFormImageRenderer绘制类,敬请大家关注。

原文地址:https://www.cnblogs.com/gc2013/p/3994459.html