码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2014-11-11 18:24:23      阅读:367      评论:0      收藏:0      [点我收藏+]

标签:des   winform   style   blog   io   color   ar   使用   sp   

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

 

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

    [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 OnLoad(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 OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            if (CDEvent.HasFlag(CDControlEvent.MouseMove))
                StateChanged(CDControlState.MouseEnter, true);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            if (CDEvent.HasFlag(CDControlEvent.MouseMove))
                StateChanged(CDControlState.MouseEnter, false);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.Button == MouseButtons.Left)
                if (CDEvent.HasFlag(CDControlEvent.MouseClick))
                    StateChanged(CDControlState.MouseDown, false);
        }

        protected override void OnMouseDown(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组件类(三)基类

标签:des   winform   style   blog   io   color   ar   使用   sp   

原文地址:http://www.cnblogs.com/ccddnet/p/4089649.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!