• C#winform自定义控件模拟设计时界面鼠标移动和调节大小、选中效果


    要想玩转Winform自定义控件需要对GDI+非常熟悉,对常用的控件有一些了解,好选择合适的基类控件来简化。

    要点说明及代码

    1)定义接口:

    using System;
    using System.Windows.Forms;
    
    namespace GDIPrinterDriver
    {
        /// <summary>
        /// 模板元素接口
        /// </summary>
        public interface ILabelDesignElement
        {
            /// <summary>
            /// PrintData/codeContext里的字段,{} [] 
            /// </summary>
            string 动态内容 { get; set; }
            /// <summary>
            /// 是否被选中
            /// </summary>
            bool DesignSelected { get; set; }
            /// <summary>
            /// 选择状态发生改变
            /// </summary>
            event Action<object, bool> SelectedStatusChange;
            /// <summary>
            /// 本控件被选中时键盘方向键被按下
            /// </summary>
            /// <param name="keyData"></param>
            void KeysChangedLocation(Keys keyData);
        }
    }

    2)控件基类实现:

    using GDIPrinterDriver;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.Windows.Forms;
    
    namespace GDILabelDesigner
    {
        /// <summary>
        /// 设计时控件基类
        /// </summary>
        public abstract class DesignCellControl : PictureBox, ILabelDesignElement
        {
            #region 鼠标移动和缩放
            private enum EnumMousePointPosition
            {
                MouseSizeNone = 0, //'无    
                MouseSizeRight = 1, //'拉伸右边框    
                MouseSizeLeft = 2, //'拉伸左边框    
                MouseSizeBottom = 3, //'拉伸下边框    
                MouseSizeTop = 4, //'拉伸上边框    
                MouseSizeTopLeft = 5, //'拉伸左上角    
                MouseSizeTopRight = 6, //'拉伸右上角    
                MouseSizeBottomLeft = 7, //'拉伸左下角    
                MouseSizeBottomRight = 8, //'拉伸右下角    
                MouseDrag = 9   // '鼠标拖动    
            }
            const int Band = 5;
            const int MinWidth = 10;
            const int MinHeight = 10;
            private EnumMousePointPosition m_MousePointPosition;
            private Point p, p1;
            private EnumMousePointPosition MousePointPosition(Size size, System.Windows.Forms.MouseEventArgs e)
            {
    
                if ((e.X >= -1 * Band) | (e.X <= size.Width) | (e.Y >= -1 * Band) | (e.Y <= size.Height))
                {
                    if (e.X < Band)
                    {
                        if (e.Y < Band) { return EnumMousePointPosition.MouseSizeTopLeft; }
                        else
                        {
                            if (e.Y > -1 * Band + size.Height)
                            { return EnumMousePointPosition.MouseSizeBottomLeft; }
                            else
                            { return EnumMousePointPosition.MouseSizeLeft; }
                        }
                    }
                    else
                    {
                        if (e.X > -1 * Band + size.Width)
                        {
                            if (e.Y < Band)
                            { return EnumMousePointPosition.MouseSizeTopRight; }
                            else
                            {
                                if (e.Y > -1 * Band + size.Height)
                                { return EnumMousePointPosition.MouseSizeBottomRight; }
                                else
                                { return EnumMousePointPosition.MouseSizeRight; }
                            }
                        }
                        else
                        {
                            if (e.Y < Band)
                            { return EnumMousePointPosition.MouseSizeTop; }
                            else
                            {
                                if (e.Y > -1 * Band + size.Height)
                                { return EnumMousePointPosition.MouseSizeBottom; }
                                else
                                { return EnumMousePointPosition.MouseDrag; }
                            }
                        }
                    }
                }
                else
                { return EnumMousePointPosition.MouseSizeNone; }
            }
            #endregion
            public bool DesignSelected
            {
                get
                {
                    return designSelected;
                }
                set
                {
                    designSelected = value;
                    Invalidate();
                }
            }
            private bool designSelected = false;
            public DynamicMapProperty DynamicMapProperty { get; set; }
            public StaticMapProperty StaticMapProperty { get; set; }
            public string 动态内容 { get; set; }
            public RoteDescription RoteDescription { get; set; }
            /// <summary>
            /// 被选中,获取到焦点的事件
            /// </summary>
            public event Action<object, bool> SelectedStatusChange;
            protected override void OnClick(EventArgs e)
            {
                DesignSelected = true;
                SelectedStatusChange?.Invoke(this, DesignSelected);
            }
            protected override void OnMouseWheel(MouseEventArgs e)
            {
                base.OnMouseWheel(e);
                double d = 1.068D;
                if (e.Delta > 0 && DesignSelected)
                {
                    this.Size = new Size((int)(this.Size.Width * d), (int)(this.Size.Height * d));
                }
                else
                {
                    this.Size = new Size((int)(this.Size.Width / d), (int)(this.Size.Height / d));
                }
            }
            protected override void OnMouseDown(MouseEventArgs e)
            {
                p.X = e.X;
                p.Y = e.Y;
                p1.X = e.X;
                p1.Y = e.Y;
            }
            protected override void OnMouseUp(MouseEventArgs e)
            {
                m_MousePointPosition = EnumMousePointPosition.MouseSizeNone;
                this.Cursor = Cursors.Arrow;
            }
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    switch (m_MousePointPosition)
                    {
                        #region 位置计算
                        case EnumMousePointPosition.MouseDrag:
                            Left = Left + e.X - p.X;
                            Top = Top + e.Y - p.Y;
                            break;
                        case EnumMousePointPosition.MouseSizeBottom:
                            Height = Height + e.Y - p1.Y;
                            p1.X = e.X;
                            p1.Y = e.Y; //'记录光标拖动的当前点    
                            break;
                        case EnumMousePointPosition.MouseSizeBottomRight:
                            Width = Width + e.X - p1.X;
                            Height = Height + e.Y - p1.Y;
                            p1.X = e.X;
                            p1.Y = e.Y; //'记录光标拖动的当前点    
                            break;
                        case EnumMousePointPosition.MouseSizeRight:
                            Width = Width + e.X - p1.X;
                            Height = Height + e.Y - p1.Y;
                            p1.X = e.X;
                            p1.Y = e.Y; //'记录光标拖动的当前点    
                            break;
                        case EnumMousePointPosition.MouseSizeTop:
                            Top = Top + (e.Y - p.Y);
                            Height = Height - (e.Y - p.Y);
                            break;
                        case EnumMousePointPosition.MouseSizeLeft:
                            Left = Left + e.X - p.X;
                            Width = Width - (e.X - p.X);
                            break;
                        case EnumMousePointPosition.MouseSizeBottomLeft:
                            Left = Left + e.X - p.X;
                            Width = Width - (e.X - p.X);
                            Height = Height + e.Y - p1.Y;
                            p1.X = e.X;
                            p1.Y = e.Y; //'记录光标拖动的当前点    
                            break;
                        case EnumMousePointPosition.MouseSizeTopRight:
                            Top = Top + (e.Y - p.Y);
                            Width = Width + (e.X - p1.X);
                            Height = Height - (e.Y - p.Y);
                            p1.X = e.X;
                            p1.Y = e.Y; //'记录光标拖动的当前点    
                            break;
                        case EnumMousePointPosition.MouseSizeTopLeft:
                            Left = Left + e.X - p.X;
                            Top = Top + (e.Y - p.Y);
                            Width = Width - (e.X - p.X);
                            Height = Height - (e.Y - p.Y);
                            break;
                        default:
                            break;
                            #endregion
                    }
                    if (Width < MinWidth) Width = MinWidth;
                    if (Height < MinHeight) Height = MinHeight;
                    if (Tag != null)
                    {                   
                        if (Tag is ImageElementNode)
                        {
                            var tag = Tag as ImageElementNode;
                            tag.Location = Location;
                        }
                        else if (Tag is BarcodeElementNode)
                        {
                            var tag = Tag as BarcodeElementNode;
                            tag.Location = Location;
                        }
                        else if (Tag is TextBoxElementNode)
                        {
                            var tag = Tag as TextBoxElementNode;
                            tag.Location = Location;
                        }
                    }
                }
                else
                {
                    m_MousePointPosition = MousePointPosition(Size, e);
                    switch (m_MousePointPosition)
                    {
                        #region 改变光标
                        case EnumMousePointPosition.MouseSizeNone:
                            this.Cursor = Cursors.Arrow;        //'箭头    
                            break;
                        case EnumMousePointPosition.MouseDrag:
                            this.Cursor = Cursors.SizeAll;      //'四方向    
                            break;
                        case EnumMousePointPosition.MouseSizeBottom:
                            this.Cursor = Cursors.SizeNS;       //'南北    
                            break;
                        case EnumMousePointPosition.MouseSizeTop:
                            this.Cursor = Cursors.SizeNS;       //'南北    
                            break;
                        case EnumMousePointPosition.MouseSizeLeft:
                            this.Cursor = Cursors.SizeWE;       //'东西    
                            break;
                        case EnumMousePointPosition.MouseSizeRight:
                            this.Cursor = Cursors.SizeWE;       //'东西    
                            break;
                        case EnumMousePointPosition.MouseSizeBottomLeft:
                            this.Cursor = Cursors.SizeNESW;     //'东北到南西    
                            break;
                        case EnumMousePointPosition.MouseSizeBottomRight:
                            this.Cursor = Cursors.SizeNWSE;     //'东南到西北    
                            break;
                        case EnumMousePointPosition.MouseSizeTopLeft:
                            this.Cursor = Cursors.SizeNWSE;     //'东南到西北    
                            break;
                        case EnumMousePointPosition.MouseSizeTopRight:
                            this.Cursor = Cursors.SizeNESW;     //'东北到南西    
                            break;
                        default:
                            break;
                            #endregion
                    }
                }
            }
    
            /// <summary>
            /// 绘制方框
            /// </summary>
            /// <param name="g"></param>
            protected void DrawSelectedStatus(Graphics g)
            {
                Rectangle rect = ClientRectangle;
                rect.Inflate(-6, -6);
                using (Pen p = new Pen(Brushes.Black, 1))
                {
                    p.DashStyle = DashStyle.Dot;
                    p.DashStyle = DashStyle.Solid;
                    //8个方块
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left - 4, rect.Top - 4, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left + rect.Width / 2 - 3, rect.Top - 4, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left + rect.Width, rect.Top - 4, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left - 4, rect.Top + rect.Height / 2 - 3, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left - 4, rect.Top + rect.Height, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left + rect.Width, rect.Top + rect.Height / 2 - 3, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left + rect.Width / 2 - 3, rect.Top + rect.Height, 4, 4));
                    g.FillRectangle(Brushes.White, new Rectangle(rect.Left + rect.Width, rect.Top + rect.Height, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left - 4, rect.Top - 4, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left + rect.Width / 2 - 3, rect.Top - 4, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left + rect.Width, rect.Top - 4, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left - 4, rect.Top + rect.Height / 2 - 3, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left - 4, rect.Top + rect.Height, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left + rect.Width, rect.Top + rect.Height / 2 - 3, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left + rect.Width / 2 - 3, rect.Top + rect.Height, 4, 4));
                    g.DrawRectangle(p, new Rectangle(rect.Left + rect.Width, rect.Top + rect.Height, 4, 4));
                }
            }
            /// <summary>
            /// 旋转图片
            /// </summary>
            /// <param name="bmp">源图</param>
            /// <param name="angle">角度</param>
            /// <param name="bkColor">背景色</param>
            /// <returns></returns>
            protected Bitmap ImageRotate(Bitmap bmp, float angle, Color bkColor)
            {
                int w = bmp.Width + 2;
                int h = bmp.Height + 2;
                PixelFormat pf;
                if (bkColor == Color.Transparent)
                {
                    pf = PixelFormat.Format32bppArgb;
                }
                else
                {
                    pf = bmp.PixelFormat;
                }
                Bitmap tmp = new Bitmap(w, h, pf);
                Graphics g = Graphics.FromImage(tmp);
                g.Clear(bkColor);
                g.DrawImageUnscaled(bmp, 1, 1);
                g.Dispose();
                GraphicsPath path = new GraphicsPath();
                path.AddRectangle(new RectangleF(0f, 0f, w, h));
                Matrix mtrx = new Matrix();
                mtrx.Rotate(angle);
                RectangleF rct = path.GetBounds(mtrx);
                Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);
                g = Graphics.FromImage(dst);
                g.Clear(bkColor);
                g.TranslateTransform(-rct.X, -rct.Y);
                g.RotateTransform(angle);
                g.InterpolationMode = InterpolationMode.HighQualityBilinear;
                g.DrawImageUnscaled(tmp, 0, 0);
                g.Dispose();
                tmp.Dispose();
                return dst;
            }
            /// <summary>
            /// 响应键盘光标键
            /// </summary>
            /// <param name="keyData"></param>
            public virtual void KeysChangedLocation(Keys keyData)
            {
                if (keyData == Keys.Up)
                {
                    Top -= 1;
                }
                if (keyData == Keys.Down)
                {
                    Top += 1;
                }
                if (keyData == Keys.Left)
                {
                    Left -= 1;
                }
                if (keyData == Keys.Right)
                {
                    Left += 1;
                }
                if (Tag != null)
                {
                    if (Tag is ImageElementNode)
                    {
                        var tag = Tag as ImageElementNode;
                        tag.Location = Location;
                    }
                    else if (Tag is BarcodeElementNode)
                    {
                        var tag = Tag as BarcodeElementNode;
                        tag.Location = Location;
                    }
                    else if (Tag is TextBoxElementNode)
                    {
                        var tag = Tag as TextBoxElementNode;
                        tag.Location = Location;
                    }
                }
            }
        }
    }
  • 相关阅读:
    微信小程序左右滚动公告栏效果
    返回当前页面title、url等操作
    打开URL操作
    打开浏览器操作
    Java for selenium(webdriver) 环境搭建
    HTMLTestRunner 自动化测试报告
    Python特殊语法:filter、map、reduce、lambda [转]
    抽象类
    __str__
    WebTable 扩展
  • 原文地址:https://www.cnblogs.com/datacool/p/datacool_2017_gdi.html
Copyright © 2020-2023  润新知