首页 > 代码库 > 制作可自定义风格的winform组件类(三)基类

制作可自定义风格的winform组件类(三)基类

一个良好的基类能决定这个控件能走多远,那么下面来定义一些事情。

 

定义状态,表示控件当前处于哪种状态,用来区别对同一事件作出不同的响应

    [Flags]    public enum CDControlState    {        None = 0,        SkinLoaded = 1,        MouseEnter = 2,        MouseDown = 4,        Resizing = 8,    }

 

定义事件,用来定制需求,忽略无用的代码,以免造成过多响应或是窗口重绘

    [Flags]    public enum CDControlEvent    {        None = 0,        MouseMove = 1,        MouseClick = 2,        BackImage = 4,        BackColor = 8,        Text = 0x10,        Icon = 0x20,    }

 

 再来定义一个接口,这是为了实现一键换肤功能,把装载素材和重定位控件内结构分别对待,同时还要在设计时把素材装填到控件相对应的属性并显示在IDE中

    public interface ICDSkin    {        void SkinLoad();        void DesigntimeSkinLoad(string name);        void CaculateLocation();    }

 

回到正题,来说说基类吧,基本雏形代码是下面这样的

namespace CDTheme{    [ToolboxItem(false)]    public abstract partial class CDBase : UserControl, ICDSkin    {        private bool _isLoaded;        private CDControlState _cdState;        private CDControlEvent _cdEvent;        protected bool IsLoaded        {            get            {                return _isLoaded;            }        }        protected CDControlState CDState        {            get            {                return _cdState;            }        }        protected CDControlEvent CDEvent        {            get            {                return _cdEvent;            }        }        private void SetCDControlState(CDControlState state, bool allow)        {            if (allow)                _cdState |= state;            else                _cdState &= ~state;        }        protected void SetCDControlEvent(CDControlEvent style, bool allow)        {            if (allow)                _cdEvent |= style;            else                _cdEvent &= ~style;        }        public void DesigntimeSkinLoad(string name)        {            CDSkinManager.DesigntimeSkinLoad(this, name);        }        public virtual void SkinLoad()        {            SetCDControlState(CDControlState.SkinLoaded, true);        }        public virtual void CaculateLocation()        {        }protected virtual void StateChanged(CDControlState changedState, bool allow)        {            SetCDControlState(changedState, allow);        }        public CDBase()        {            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);            InitializeComponent();        }        [Browsable(false)]        public new BorderStyle BorderStyle        {            get            {                return base.BorderStyle;            }            set            {                base.BorderStyle = value;            }        }        protected override void onl oad(EventArgs e)        {            _isLoaded = true;            base.OnLoad(e);        }        protected override void OnSizeChanged(EventArgs e)        {            base.OnSizeChanged(e);            if (CDState.HasFlag(CDControlState.SkinLoaded))                CaculateLocation();        }        protected override void OnEnabledChanged(EventArgs e)        {            base.OnEnabledChanged(e);            StateChanged(CDControlState.None, true);        }        protected override void onm ouseEnter(EventArgs e)        {            base.OnMouseEnter(e);            if (CDEvent.HasFlag(CDControlEvent.MouseMove))                StateChanged(CDControlState.MouseEnter, true);        }        protected override void onm ouseLeave(EventArgs e)        {            base.OnMouseLeave(e);            if (CDEvent.HasFlag(CDControlEvent.MouseMove))                StateChanged(CDControlState.MouseEnter, false);        }        protected override void onm ouseUp(MouseEventArgs e)        {            base.OnMouseUp(e);            if (e.Button == MouseButtons.Left)                if (CDEvent.HasFlag(CDControlEvent.MouseClick))                    StateChanged(CDControlState.MouseDown, false);        }        protected override void onm ouseDown(MouseEventArgs e)        {            base.OnMouseDown(e);            if (e.Button == MouseButtons.Left)                if (CDEvent.HasFlag(CDControlEvent.MouseClick))                    StateChanged(CDControlState.MouseDown, true);        }    }}

虽然没有注释,但通过名称大家也能明白意思,封装了常用的事件并统一到StateChanged方法中,让派生类通过重写此方法来作出独立的响应

那么如何使用这个基类?

一、在每个在有实际代码派生类的构造函数中使用SetCDControlEvent来决定当些事件会被响应

二、通过重写SkinLoad、CaculateLocation与StateChanged三个方法,来达到装载素材、重新定位与事件响应的效果

三、根据需求定义属性与实现界面的逻辑

 

说得很抽象,在下一篇将会给出一个简单的实例来说明

 

制作可自定义风格的winform组件类(三)基类