• 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绘制类,敬请大家关注。

  • 相关阅读:
    微服务划分的姿势
    微服务的时间和成本去哪儿了
    假如你是架构师,你要做些什么
    说透代码评审
    从哲学层面浅谈计算机学习方法论
    分布式事务:两阶段提交与三阶段提交
    敏捷史话(四):敏捷是人的天性 —— Arie van Bennekum
    敏捷史话(三):笃定前行的勇者——Ken Schwaber
    敏捷史话(二):Scrum社区的悲剧性损失——Mike Beedle
    敏捷史话(一):用一半的时间做两倍的事——Scrum之父Jeff Sutherland
  • 原文地址:https://www.cnblogs.com/gc2013/p/3994459.html
Copyright © 2020-2023  润新知