C# 轻松实现对窗体(Form)换肤_Kyle's BLOG_百度空间

转自

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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3、 OnRenderSkinFormBorder:绘制窗体边框。

4、 OnRenderSkinFormBackground:绘制窗体背景。

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

看看SkinFormRenderer的完整代码:

public abstract class SkinFormRenderer

    {

        #region Fields
        private EventHandlerList _events;
        private static readonly object EventRenderSkinFormCaption = new object();

        private static readonly object EventRenderSkinFormBorder = new object();

        private static readonly object EventRenderSkinFormBackground = new object();

        private static readonly object EventRenderSkinFormControlBox = new object();
        #endregion
        #region Constructors
        protected SkinFormRenderer()

        {

        }
        #endregion
        #region Properties
        protected EventHandlerList Events

        {

            get

            {

                if (_events == null)

                {

                    _events = new EventHandlerList();

                }

                return _events;

            }

        }
        #endregion
        #region Events
        public event SkinFormCaptionRenderEventHandler RenderSkinFormCaption

        {

            add { AddHandler(EventRenderSkinFormCaption, value); }

            remove { RemoveHandler(EventRenderSkinFormCaption, value); }

        }
        public event SkinFormBorderRenderEventHandler RenderSkinFormBorder

        {

            add { AddHandler(EventRenderSkinFormBorder, value); }

            remove { RemoveHandler(EventRenderSkinFormBorder, value); }

        }
        public event SkinFormBackgroundRenderEventHandler RenderSkinFormBackground

        {

            add { AddHandler(EventRenderSkinFormBackground, value); }

            remove { RemoveHandler(EventRenderSkinFormBackground, value); }

        }
        public event SkinFormControlBoxRenderEventHandler RenderSkinFormControlBox

        {

            add { AddHandler(EventRenderSkinFormControlBox, value); }

            remove { RemoveHandler(EventRenderSkinFormControlBox, value); }

        }
        #endregion
        #region Public Methods
        public abstract Region CreateRegion(SkinForm form);
        public abstract void InitSkinForm(SkinForm form);
        public void DrawSkinFormCaption(

            SkinFormCaptionRenderEventArgs e)

        {

            OnRenderSkinFormCaption(e);

            SkinFormCaptionRenderEventHandler handle =

                Events[EventRenderSkinFormCaption]

                as SkinFormCaptionRenderEventHandler;

            if (handle != null)

            {

                handle(this, e);

            }

        }        public void DrawSkinFormBorder(

            SkinFormBorderRenderEventArgs e)

        {

            OnRenderSkinFormBorder(e);

            SkinFormBorderRenderEventHandler handle =

                Events[EventRenderSkinFormBorder]

                as SkinFormBorderRenderEventHandler;

            if (handle != null)

            {

                handle(this, e);

            }

        }        public void DrawSkinFormBackground(

            SkinFormBackgroundRenderEventArgs e)

        {

            OnRenderSkinFormBackground(e);

            SkinFormBackgroundRenderEventHandler handle =

                Events[EventRenderSkinFormBackground]

                as SkinFormBackgroundRenderEventHandler;

            if (handle != null)

            {

                handle(this, e);

            }

        }
        public void DrawSkinFormControlBox(

            SkinFormControlBoxRenderEventArgs e)

        {

            OnRenderSkinFormControlBox(e);

            SkinFormControlBoxRenderEventHandler handle =

                Events[EventRenderSkinFormControlBox]

                as SkinFormControlBoxRenderEventHandler;

            if (handle != null)

            {

                handle(this, e);

            }

        }
        #endregion
        #region Protected Render Methods
        protected abstract void OnRenderSkinFormCaption(

            SkinFormCaptionRenderEventArgs e);
        protected abstract void OnRenderSkinFormBorder(

            SkinFormBorderRenderEventArgs e);
        protected abstract void OnRenderSkinFormBackground(

            SkinFormBackgroundRenderEventArgs e);
        protected abstract void OnRenderSkinFormControlBox(

            SkinFormControlBoxRenderEventArgs e);
        #endregion
        #region Protected Methods
        [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]

        protected void AddHandler(object key, Delegate value)

        {

            Events.AddHandler(key, value);

        }
        [UIPermission(SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]

        protected void RemoveHandler(object key, Delegate value)

        {

            Events.RemoveHandler(key, value);

        }
        #endregion

    }

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

声明:

本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。



郑重声明:资讯 【C# 轻松实现对窗体(Form)换肤_Kyle's BLOG_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——