栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C#在控件中绘制矩形、圆、线段等(切换不同的图片,自定义翻页控件,通过委托监控某个字段)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#在控件中绘制矩形、圆、线段等(切换不同的图片,自定义翻页控件,通过委托监控某个字段)

1.效果展示

2 自定义翻页控件

    public partial class PageManagemen : UserControl
    {
        /// 
        /// 当前页(从1开始计数)
        /// 
        private int _currentPage = 1;

        /// 
        /// 总数
        /// 
        private static int _dataSum;

        /// 
        ///设置总数
        /// 
        /// 总数
        public void SetDataSum(int dataSum)
        {
            _dataSum = dataSum;
            btn_Click(null, null);
            comboBox1.Items.Clear();
            for (int i = 0; i < dataSum; i++)
            {
                comboBox1.Items.Add((i + 1).ToString());
            }
            comboBox1.SelectedIndex = _currentPage - 1;
        }


        public PageManagemen()
        {
            InitializeComponent();
        }

        //点击事件
        public void btn_Click(object sender, EventArgs e)
        {
            try
            {
                Button btn = (Button)sender;
                if (btn == btn_First)
                {
                    _currentPage = 1;
                }
                else if (btn == btn_Up)
                {
                    --_currentPage;
                    if (_currentPage < 1)
                    {
                        _currentPage = _dataSum;
                    }
                }
                else if (btn == btn_Down)
                {
                    _currentPage = (_currentPage + 1) % _dataSum;
                    if (_currentPage == 0)
                    {
                        _currentPage = _dataSum;
                    }
                }
                else if (btn == btn_Last)
                {
                    _currentPage = _dataSum;
                }
                lbl_info.Text = $"第{_currentPage}页,共{_dataSum}页";
                comboBox1.SelectedIndex = _currentPage - 1;
                Form1.CurrentPage = _currentPage;
            }
            catch (Exception)
            {

            }
        }

    }
3 主界面事件
    /// 
    /// 声明委托,用于监控当前页变量
    /// 
    delegate void CurrentPageDelegate();

    public partial class Form1 : Form
    {
        /// 
        /// 指令目录的根目录下所有图片路径
        /// 
        private List _lstPath;
        /// 
        /// 存储当前显示图像
        /// 
        private Bitmap _bitmap;
        /// 
        /// 当前显示图像的索引
        /// 
        private static int _currentPage;
        /// 
        /// 利用属性执行委托
        /// 
        public static int CurrentPage
        {
            set
            {
                _currentPage = value - 1;
                CurrentPageEvent?.Invoke();
            }
        }
        /// 
        /// 记录鼠标移动时的位置
        /// 
        private Point _mouseDown, _mouseLocation;
        /// 
        /// 是否允许绘制管理
        /// 
        private bool _banDraw = true;
        /// 
        /// 绘图类型
        /// 
        private DrawTool.DrawType _drawType;
        /// 
        /// 存放猫猫的窝
        /// 
        private readonly string _catDirectory = Application.StartupPath + @"Cat";


        /// 
        /// 定义委托
        /// 
        private static event CurrentPageDelegate CurrentPageEvent;

        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                CurrentPageEvent += UpdataImage;//添加委托事件

                var ret = DrawTool.DicDrawType.Keys;
                foreach (var s in ret)
                {
                    comboBox1.Items.Add(s);
                }
                comboBox1.SelectedIndex = 0;

                //搭建猫窝
                if (!Directory.Exists(_catDirectory))
                {
                    Directory.CreateDirectory(_catDirectory);
                }

                GetFilesByDirectory();

            }
            catch (Exception)
            {

            }
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            pic_1.Refresh();
        }



        public void UpdataImage()
        {
            try
            {
                _bitmap?.Dispose();
                pic_1.Focus();
                _bitmap = (Bitmap)Image.FromFile(_lstPath[_currentPage], false);
                pic_1.Image = _bitmap;
                pic_1.Refresh();
            }
            catch (Exception)
            {

            }
        }

        /// 
        /// 获取文件信息,并设置相关参数
        /// 
        private void GetFilesByDirectory()
        {
            try
            {
                var extension = new[] { "png", "jpg", "JPEG", "BMP" };
                var di = new DirectoryInfo(_catDirectory);
                const string start = "*";
                var lst = extension.Select(s => start + s).ToList();
                var fileInfos = lst.SelectMany(i => di.GetFiles(i.ToLower(), SearchOption.TopDirectoryOnly)).Distinct().ToArray();
                _lstPath = fileInfos.Select(fileInfo => fileInfo.FullName).ToList();

                page.SetDataSum(fileInfos.Length);

                if (_lstPath.Count > 0)
                {
                    _bitmap = null;//释放当前图像,以便加载新图像
                    _bitmap = (Bitmap)Image.FromFile(_lstPath[_currentPage], false);
                }
            }
            catch (Exception)
            {

            }
        }



        #region [PictureBox事件管理]

        //绘制类型选择
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            _drawType = DrawTool.DicDrawType[comboBox1.Text];
            pic_1.Refresh();
        }

        //切换图像(在pictureBox鼠标移动事件中设置焦点)
        private void pic_1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            switch ((Keys)e.KeyValue)
            {
                case Keys.Up:
                case Keys.Left:
                case Keys.W:
                case Keys.A:
                    page.btn_Click(page.btn_Up, null);
                    break;
                case Keys.Down:
                case Keys.Right:
                case Keys.S:
                case Keys.D:
                    page.btn_Click(page.btn_Down, null);
                    break;
                case Keys.End:
                    page.btn_Click(page.btn_Last, null);
                    break;
                case Keys.Home:
                    page.btn_Click(page.btn_First, null);
                    break;
            }
        }

        //鼠标按下开启绘图
        private void pic_1_MouseDown(object sender, MouseEventArgs e)
        {
            if (MouseButtons.Left != e.Button) return;
            _banDraw = false;
            _mouseDown = e.Location;
        }

        //鼠标按下停止绘图
        private void pic_1_MouseUp(object sender, MouseEventArgs e)
        {
            if (MouseButtons.Left != e.Button) return;
            _banDraw = true;
        }

        //鼠标移动事件
        private void pic_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                pic_1.Focus();
                if (_banDraw) return;
                _mouseLocation = e.Location;
                pic_1.Refresh();
            }
            catch (Exception)
            {

            }
        }

        //绘图事件
        private void pic_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                var pic = (PictureBox)sender;

                e.Graphics.Clear(Color.SkyBlue);//清除整个绘图面并以指定背景色填充

				ref int magnify = 0;
                DrawTool.DrawImage(e.Graphics, _bitmap, ref magnify, pic.Size);

                if (_mouseDown.X == 0) return;

                switch (_drawType)
                {
                    case DrawTool.DrawType.Rect:
                        DrawTool.DrawRect(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                    case DrawTool.DrawType.Line:
                        DrawTool.DrawLine(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                    case DrawTool.DrawType.Cross:
                        DrawTool.DrawCross(e.Graphics, _mouseLocation, pic.Size);
                        break;
                    case DrawTool.DrawType.EquicruralTriangle:
                        DrawTool.DrawEquicruralTriangle(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                    case DrawTool.DrawType.RhombusUpToDown:
                        DrawTool.DrawRhombusUpToDown(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                    case DrawTool.DrawType.RhombusLeftToRight:
                        DrawTool.DrawRhombusLeftToRight(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                    case DrawTool.DrawType.Circle:
                        DrawTool.DrawCircle(e.Graphics, _mouseDown, _mouseLocation);
                        break;
                }
            }
            catch (Exception)
            {

            }
        }

        #endregion


        //捉猫猫
        private void button1_Click(object sender, EventArgs e)
        {
            var dialog = new OpenFileDialog
            {
                Filter = "|*.png;*.jpg;*.JPEG;*.BMP",
                Multiselect = true
            };
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int num = 0;
                foreach (var filename in dialog.FileNames)
                {
                    string path = _catDirectory + @"" + Path.GetFileName(filename);
                    if (File.Exists(path)) continue;
                    num++;
                    File.Copy(filename, path, true);
                }
                MessageBox.Show($"恭喜您,已经捉住了{num}只猫猫。", "提示");
            }
            dialog.Dispose();
            GetFilesByDirectory();
        }

        //放猫猫
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                var dialog = new OpenFileDialog
                {
                    Filter = "|*.png;*.jpg;*.JPEG;*.BMP",
                    Multiselect = false,
                    InitialDirectory = _catDirectory
                };
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    string path = dialog.FileName;
                    dialog.Dispose();
                    if (Path.GetDirectoryName(path) != _catDirectory)
                        return;
                    _bitmap?.Dispose();
                    File.Delete(path);
                    GetFilesByDirectory();
                    MessageBox.Show("恭喜您,已经放生了一只猫猫。", "提示");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                MessageBox.Show("猫猫被禁闭无法释放,试试放别的猫猫。", "提示");
            }

        }

    }
4 绘制工具类
public class DrawTool
    {

        public static Dictionary DicDrawType;

        public enum DrawType
        {
            Null,
            /// 
            /// 清除整个绘图面并以指定背景色填充
            /// 
            Clear,
            /// 
            /// 绘制图像
            /// 
            Image,
            /// 
            /// 矩形
            /// 
            Rect,
            /// 
            /// 线段
            /// 
            Line,
            /// 
            /// 十字
            /// 
            Cross,
            /// 
            /// 等腰三角形
            /// 
            EquicruralTriangle,
            /// 
            /// 菱形
            /// 
            Rhombus,
            /// 
            /// 空心圆
            /// 
            HollowCircle,
            /// 
            /// 实心圆
            /// 
            SolidCircle,
            /// 
            /// 文字
            /// 
            String,
        }

        static DrawTool()
        {
            DicDrawType = new Dictionary
            {
                {"矩形",DrawType.Rect},
                {"线段",DrawType.Line},
                {"十字",DrawType.Cross},
                {"等腰三角形",DrawType.EquicruralTriangle},
                {"菱形",DrawType.Rhombus},
                {"空心圆",DrawType.HollowCircle},
                {"实心圆",DrawType.SolidCircle},
                {"文字",DrawType.String},
            };
        }

        /// 
        /// 清除整个绘图面并以指定背景色填充
        /// 
        /// 
        public static void DrawClear(Graphics e)
        {
            e.Clear(Color.SkyBlue);
        }

        /// 
        /// 绘制图像
        /// 
        /// 绘画类
        /// 图像
        /// 图像放大倍率
        /// 承载图像的父控件大小
        public static void DrawImage(Graphics e, Bitmap bmp, ref int magnify, Size size)
        {
            var rectBmpPos = new Rectangle();//获取图像显示的位置和宽、高信息
            //父控件大小 和Bitmap 的宽高比
            var picByBmpScale = Math.Min((float)size.Width / bmp.Width, (float)size.Height / bmp.Height);
            rectBmpPos.Width = (int)(bmp.Width * picByBmpScale);
            rectBmpPos.Height = (int)(bmp.Height * picByBmpScale);
            rectBmpPos.X = (size.Width - rectBmpPos.Width) / 2;
            rectBmpPos.Y = (size.Height - rectBmpPos.Height) / 2;

            #region [根据放大倍率,计算图像显示区域]
            int nMaxMagnify = Math.Min(bmp.Width, bmp.Height) / 2;//最大放大倍率
            if (magnify >= nMaxMagnify)
            {
                magnify = nMaxMagnify - 1;
            }
            var pointMagnify = new Size(bmp.Width / 2 / nMaxMagnify, bmp.Height / 2 / nMaxMagnify);//每一倍放大的像素值
            int x = magnify * pointMagnify.Width;
            int y = magnify * pointMagnify.Height;
            int width = bmp.Width - magnify * pointMagnify.Width * 2;
            int height = bmp.Height - magnify * pointMagnify.Height * 2;
            #endregion [根据放大倍率,计算图像显示区域]

            var rectBmpSize = new Rectangle(x, y, width, height);//图像显示的区域
            e.SmoothingMode = SmoothingMode.HighQuality;//指定抗锯齿的呈现
            e.DrawImage(bmp, rectBmpPos, rectBmpSize, GraphicsUnit.Pixel);//绘制图像

            //bmp.Dispose();

        }

        /// 
        /// 绘制矩形
        /// 
        /// 
        /// 起始点
        /// 终止点
        public static void DrawRect(Graphics e, Point startPoint, Point endPoint)
        {
            var pen = new Pen(Brushes.Brown, 3);
            var x1 = startPoint.X;
            var y1 = startPoint.Y;
            var x2 = endPoint.X;
            var y2 = endPoint.Y;
            if (x1 > x2)
            {
                x1 = x1 + x2;
                x2 = x1 - x2;
                x1 = x1 - x2;
            }
            if (y1 > y2)
            {
                y1 = y1 + y2;
                y2 = y1 - y2;
                y1 = y1 - y2;
            }
            e.DrawRectangle(pen, x1, y1, x2 - x1, y2 - y1);
        }

        /// 
        /// 绘制线段
        /// 
        /// 
        /// 起始点
        /// 终止点
        public static void DrawLine(Graphics e, Point startPoint, Point endPoint)
        {
            var brush = new SolidBrush(Color.FromArgb(127, Color.Black));
            var pen = new Pen(Brushes.Brown, 3);
            var x1 = startPoint.X;
            var y1 = startPoint.Y;
            var x2 = endPoint.X;
            var y2 = endPoint.Y;
            e.FillEllipse(brush, x1 - 3, y1 - 3, 6, 6); //绘制一个椭圆,填充内部颜色,可以代表一个点
            e.FillEllipse(brush, x2 - 3, y2 - 3, 6, 6); //绘制一个椭圆,填充内部颜色,可以代表一个点
            e.DrawLine(pen, x1, y1, x2, y2); //绘制一条直线 
        }

        /// 
        /// 绘制十字
        /// 
        /// 
        /// 指定坐标点
        /// 控件大小
        public static void DrawCross(Graphics e, Point point, Size size)
        {
            var pen = new Pen(Brushes.Yellow, 1);
            int radius = Math.Min(size.Width, size.Height) / 2 - 4;
            e.DrawLine(pen, point.X, point.Y - radius, point.X, point.Y + radius); //绘制垂直条
            e.DrawLine(pen, point.X - radius, point.Y, point.X + radius, point.Y); //绘制水平线条
            //DrawString(e, point, size);//绘制坐标文字信息
        }

        /// 
        /// 绘制等腰三角形
        /// 
        /// 
        /// 顶点
        /// 底边任意一点
        public static void DrawEquicruralTriangle(Graphics e, Point point1, Point point2)
        {
            var pen = new Pen(Brushes.Brown, 3);
            Point[] points = new Point[4];
            points[0] = point1;
            points[1] = point2;
            points[2] = new Point(point2.X + 2 * (point1.X - point2.X), point2.Y);
            points[3] = point1;
            e.DrawPolygon(pen, points);
        }

        /// 
        /// 绘制菱形
        /// 
        /// 
        /// 起始点
        /// 终止点
        public static void DrawRhombus(Graphics e, Point startPoint, Point endPoint)
        {
            int diff = endPoint.Y - startPoint.Y;
            float x1 = startPoint.X;
            float x2 = endPoint.X;
            float y1 = startPoint.Y;
            float y2 = endPoint.Y;
            Calculate(ref x1, ref x2, ref y1, ref y2);
            var pen = new Pen(Brushes.Brown, 3);
            Point[] points = new Point[5];
            points[0] = startPoint;
            points[1] = new Point((int)x1, (int)y1);
            points[2] = endPoint;
            points[3] = new Point((int)x2, (int)y2);
            points[4] = startPoint;
            e.DrawPolygon(pen, points);
        }

        /// 
        /// 绘制空心圆
        /// 
        /// 
        /// 圆心
        /// 确定圆半径的第二个点
        public static void DrawHollowCircle(Graphics e, Point point1, Point point2)
        {
            var pen = new Pen(Brushes.Brown, 3);
            float x1 = point1.X;
            float x2 = point2.X;
            float y1 = point1.Y;
            float y2 = point2.Y;
            float diameter = (float)Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));//半径
            var rect = new RectangleF
            {
                X = point1.X - diameter,
                Y = point1.Y - diameter,
                Width = 2 * diameter,
                Height = 2 * diameter
            };
            e.DrawEllipse(pen, rect);
            //DrawSolidCircle(e, point1, 6);//画圆心
            //DrawSolidCircle(e, new Point(point2.X - 3, point2.Y - 3), 6);//确定圆半径的第二个点
        }

        /// 
        /// 绘制实心圆
        /// 
        /// 
        /// 圆心
        /// 半径
        public static void DrawSolidCircle(Graphics e, Point point1, int nCircle)
        {
            var brush = new SolidBrush(Color.FromArgb(127, Color.Black));
            e.FillEllipse(brush, point1.X, point1.Y, nCircle, nCircle); //绘制圆心
        }
        
        /// 
        /// 在指定坐标点绘制文字
        /// 
        /// 
        /// 指定坐标点
        /// 控件大小
        /// 绘制文字的信息
        public static void DrawString(Graphics e, Point point, Size size, string info = null)
        {
            if (string.IsNullOrWhiteSpace(info))
            {
                info = $"({point.X},{point.Y})";
            }
            Font font = new Font("Arial", 12f, FontStyle.Bold);//设置字体
            SizeF selPtStrSize = e.MeasureString(info, font); //获取文字的宽高

            if (point.X > size.Width / 2 && point.Y < size.Height / 2) //右上角
            {
                point.X -= (int)selPtStrSize.Width;
            }
            else if (point.X > size.Width / 2 && point.Y > size.Height / 2) //右下角
            {
                point.X -= (int)selPtStrSize.Width;
                point.Y -= (int)selPtStrSize.Height;
            }
            else if (point.X < size.Width / 2 && point.Y > size.Height / 2) //左下角
            {
                point.Y -= (int)selPtStrSize.Height;
            }

            e.DrawString(info, font, new SolidBrush(Color.Black), point); //绘制文字
        }
        
        /// 
        /// 已知两点(线段),求互相垂直平分两点(线段)。
        /// 
        /// 传递值为已知坐标点x1,返回值为垂直平分线的x1
        /// 传递值为已知坐标点x2,返回值为垂直平分线的x2
        /// 传递值为已知坐标点y1,返回值为垂直平分线的y1
        /// 传递值为已知坐标点y2,返回值为垂直平分线的y2
        /// 成功返回0;失败返回非0
        private static int Calculate(ref float x1, ref float x2, ref float y1, ref float y2)
        {
            float k1 = 1; //已知坐标点直线的斜率k值
            float b1 = 1; //已知坐标点直线的纵截距b值
            float k2 = 1; //垂直平分线的斜率k值
            float b2 = 1; //垂直平分线的纵截距b值

            try
            {
                //特殊线1
                if (x1 == x2)
                {
                    float center = (y1 + y2) / 2;//中心点
                    float dist = Math.Abs(y1 - center);//端点到中心点的距离值
                    x1 = center - dist;
                    x2 = center + dist;
                    y2 = y1 = (x1 + x2) / 2;
                    return 0;
                }

                //特殊线2
                if (y1 == y2)
                {
                    float center = (x1 + x2) / 2;//中心点
                    float dist = Math.Abs(x1 - center);//端点到中心点的距离值
                    x1 = x2 = (y1 + y2) / 2;
                    y1 = center - dist;
                    y2 = center + dist;
                    return 0;
                }

                #region [求已知曲线的k和b]
                float temp = 0;
                float coefficient; //系数值
                if (x1 >= x2)
                {
                    coefficient = (float)Math.Round((x1 / x2), 2);
                    temp = y2 * coefficient; //将对应的函数乘以系数
                    b1 = (float)Math.Round(((temp - y1) / (coefficient - 1)), 2); //求出b值
                    k1 = (float)Math.Round(((y1 - b1) / x1), 2); //求出k值
                }
                else
                {
                    coefficient = x2 / x1;
                    temp = y1 * coefficient;
                    b1 = (float)Math.Round(((temp - y2) / (coefficient - 1)), 2); //求出b值
                    k1 = (float)Math.Round(((y2 - b1) / x2), 2); //求出k值
                }
                #endregion [求已知曲线的k和b]

                #region [垂直平分线的k,b以及起始点、终止点]
                {
                    k2 = -1 / k1; //垂直平分线的斜率k值
                    b2 = (x1 + x2) / (2 * k1) + (y1 + y2) / 2; //垂直平分线的纵截距b值
                    double cenX = (x1 + x2) / 2;//交点x
                    double cenY = (y1 + y2) / 2;//交点y
                    double dist = Math.Sqrt(Math.Abs(x1 - x2) * Math.Abs(x1 - x2) + Math.Abs(y1 - y2) * Math.Abs(y1 - y2)) / 2;//每个点距离交点(中心点)距离相同
                    double douAngle = Math.Atan(k2);//垂直平分线和X轴的夹角

                    //计算起始点和终止点
                    x1 = (float)(cenX + dist * Math.Cos(douAngle));
                    x2 = (float)(cenX - dist * Math.Cos(douAngle));
                    y1 = (float)(cenY + dist * Math.Sin(douAngle));
                    y2 = (float)(cenY - dist * Math.Sin(douAngle));
                }
                #endregion

                return 0;
            }
            catch
            {
                return -1;
            }
        }

    }
           ```

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/909335.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号