Form:http://blog.csdn.net/hbxtlhx/archive/2007/08/31/1766913.aspx

使用C#在Windows应用程序里绘图,可能用到移动图像、擦掉图像,调整大小等等。我这里有一个画图的小程序,简单的实现了这些。。。

定义图像的基类:

abstract class DrawBase
...{
    internal Color m_BackColor;
    internal Color m_ForeColor;
    internal static int m_HalfGrab;

    public static int HalfGrab
    ...{
        get ...{ return DrawBase.m_HalfGrab; }
        set ...{ DrawBase.m_HalfGrab = value; }
    }

    public Color BackColor
    ...{
        get ...{ return m_BackColor; }
        set ...{ m_BackColor = value; }
    }

    public Color ForeColor
    ...{
        get ...{ return m_ForeColor; }
        set ...{ m_ForeColor = value; }
    }

    public abstract Rectangle GetBound();
    public abstract void Draw(Graphics g);
    public abstract bool Near(int x, int y);
    public abstract void SetBound(Rectangle bound);
}

定义线:

class LineObj:DrawBase
...{
    private Point m_Start;
    private Point m_End;
    public LineObj(Point start, Point end)
    ...{
        this.m_Start = start;
        this.m_End = end;
    }
    public override System.Drawing.Rectangle GetBound()
    ...{
        int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
        int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
        int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
        int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
        return Rectangle.FromLTRB(x, y, r, b);
    }

    public override void Draw(System.Drawing.Graphics g)
    ...{
        using (Pen pen = new Pen(this.m_ForeColor))
        ...{
            g.DrawLine(pen, this.m_Start, this.m_End);
        }
    }

    public override bool Near(int x, int y)
    ...{
        //点到直线的距离是否在抓取范围之内
        float A = this.m_End.Y- this.m_Start.Y;
        float B = this.m_End.X- this.m_Start.X;
        float C = B * this.m_Start.Y - A * this.m_Start.X;
        double D = (A * x - B * y + C) / (Math.Sqrt(A * A + B * B));
        if (D >= -m_HalfGrab && D <= m_HalfGrab)
        ...{
            RectangleF bounds = this.GetBound();
            bounds.Inflate(m_HalfGrab, m_HalfGrab);
            return bounds.Contains(x, y);
        }
        return false;
    }

    public override void SetBound(Rectangle bound)
    ...{
        this.m_Start = new Point(bound.X, bound.Y);
        this.m_End = new Point(bound.Right, bound.Bottom);
    }
}

定义矩形:

class RectangleObj:DrawBase
...{
    private Point m_Start;
    private Point m_End;
    private bool m_Solid;
    public RectangleObj(Point start, Point end)
    ...{
        this.m_Start = start;
        this.m_End = end;
    }
    public bool Solid
    ...{
        get ...{ return m_Solid; }
        set ...{ m_Solid = value; }
    }
    public override System.Drawing.Rectangle GetBound()
    ...{
        int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
        int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
        int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
        int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
        return Rectangle.FromLTRB(x, y, r, b);
    }

    public override void Draw(Graphics g)
    ...{
        Rectangle bound = this.GetBound();
        if (this.m_Solid)
        ...{
            using (SolidBrush brush = new SolidBrush(this.m_BackColor))
            ...{
                g.FillRectangle(brush, bound);
            }
        }
        using (Pen pen = new Pen(this.m_ForeColor))
        ...{
            g.DrawRectangle(pen, bound);
        }
    }

    public override bool Near(int x, int y)
    ...{
        Rectangle bound = this.GetBound();
        Rectangle inner = bound;
        Rectangle outer = bound;
        inner.Inflate(-m_HalfGrab, -m_HalfGrab);
        outer.Inflate(m_HalfGrab, m_HalfGrab);
        Region reg = new Region(outer);
        reg.Exclude(inner);
        return reg.IsVisible(x, y);
    }

    public override void SetBound(Rectangle bound)
    ...{
        this.m_Start = new Point(bound.X, bound.Y);
        this.m_End = new Point(bound.Right, bound.Bottom);
    }
}

当然也可以绘制Window控件:

class ButtonObj:DrawBase
...{
    private Point m_Start;
    private Point m_End;
    private string m_Text;
    public ButtonObj(Point start, Point end)
    ...{
        this.m_Start = start;
        this.m_End = end;
    }
    public string Text
    ...{
        get ...{ return m_Text; }
        set ...{ m_Text = value; }
    }
    public override System.Drawing.Rectangle GetBound()
    ...{
        int x = this.m_Start.X < this.m_End.X ? this.m_Start.X : this.m_End.X;
        int y = this.m_Start.Y < this.m_End.Y ? this.m_Start.Y : this.m_End.Y;
        int r = this.m_Start.X < this.m_End.X ? this.m_End.X : this.m_Start.X;
        int b = this.m_Start.Y < this.m_End.Y ? this.m_End.Y : this.m_Start.Y;
        return Rectangle.FromLTRB(x, y, r, b);
    }

    public override void Draw(Graphics g)
    ...{
        Rectangle bound = this.GetBound();
        using (Pen pen = new Pen(this.m_ForeColor))
        ...{
            ControlPaint.DrawButton(g, bound, ButtonState.Normal);
            using (SolidBrush brush = new SolidBrush(this.m_ForeColor))
            ...{
                using (Font font = new Font("宋体", 10))
                ...{
                    using (StringFormat format = new StringFormat())
                    ...{
                        format.Alignment = StringAlignment.Center;
                        format.LineAlignment = StringAlignment.Center;
                        g.DrawString(this.m_Text, font, brush, bound, format);
                    }
                }
            }
        }
    }

    public override bool Near(int x, int y)
    ...{
        Rectangle bound = this.GetBound();
        Rectangle outer = bound;
        outer.Inflate(m_HalfGrab, m_HalfGrab);
        return outer.Contains(x, y);
    }

    public override void SetBound(Rectangle bound)
    ...{
        this.m_Start = new Point(bound.X, bound.Y);
        this.m_End = new Point(bound.Right, bound.Bottom);
    }
}

定义这些图像的集合对象:

class DrawList:List<DrawBase>
...{
    private Control m_Owner;
    public DrawList(Control owner)
    ...{ 
        this.m_Owner = owner;
    }
    internal DrawBase GetNear(int x, int y)
    ...{
        foreach (DrawBase draw in this)
        ...{
            if (draw.Near(x, y))
            ...{
                return draw;
            }
        }
        return null;
    }

    internal void Draw(Graphics graphics)
    ...{
        foreach (DrawBase draw in this)
        ...{
            draw.Draw(graphics);
        }
    }
}

构建一个Window窗体用来展示图像操作:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DrawLines.DrawObjs;

namespace DrawLines
...{
    public partial class Form1 : Form
    ...{
        private DrawList m_drawList;
        private DrawBase m_curDraw;
        private Rectangle m_curBound;
        private Rectangle m_lastBound;
        private Point m_StartPoint;
        public Form1()
        ...{
            InitializeComponent();
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);

            this.InitObjs();
        }
        /**//// <summary>
        /// 构造对象
        /// </summary>
        private void InitObjs()
        ...{
            this.m_drawList = new DrawList(this);

            DrawBase.HalfGrab = 5;
            LineObj line0 = new LineObj(new Point(10, 10), new Point(100, 100));
            line0.ForeColor = Color.Red;

            LineObj line1 = new LineObj(new Point(16, 67), new Point(100, 180));
            line1.ForeColor = Color.Blue;

            RectangleObj rect = new RectangleObj(new Point(120, 70), new Point(220, 200));
            rect.ForeColor = Color.Green;

            ButtonObj button = new ButtonObj(new Point(20, 20), new Point(90, 45));
            button.ForeColor = Color.Black;
            button.Text = "button1";
            m_drawList.Add(line0);
            m_drawList.Add(line1);
            m_drawList.Add(rect);
            m_drawList.Add(button);
        }
        /**//// <summary>
        /// 绘制对象
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        ...{
            this.m_drawList.Draw(e.Graphics);
            base.OnPaint(e);
        }
        /**//// <summary>
        /// 重写以移动对象或设置鼠标
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(MouseEventArgs e)
        ...{
            base.OnMouseMove(e);
            if (this.Capture)
            ...{
                if (this.m_curDraw != null)
                ...{
                    this.moveObj(e);
                }
                return;
            }
            if (this.m_drawList.GetNear(e.X, e.Y) != null)
            ...{
                this.Cursor = Cursors.SizeAll;
            }
            else
            ...{
                this.Cursor = Cursors.Default;
            }
        }
        /**//// <summary>
        /// 重写以获取鼠标下的对象
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        ...{
            base.OnMouseDown(e);
            this.getObj(e);
        }
        /**//// <summary>
        /// 重写以按Delete键删除当前对象
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        ...{
            if (keyData == Keys.Delete)
            ...{
                if (this.m_curDraw != null)
                ...{
                    this.deleteObj();
                }
            }
            return base.ProcessDialogKey(keyData);
        }
        private void btnDelete_Click(object sender, EventArgs e)
        ...{
            if (this.m_curDraw != null)
            ...{
                this.deleteObj();
            }
            else
            ...{
                MessageBox.Show(this, "没有选中的对象,请使用鼠标点选择一个!", "提示");
            }
        }
        private void moveObj(MouseEventArgs e)
        ...{
            Rectangle bound = this.m_curBound;

            bound.Offset(e.X - this.m_StartPoint.X, e.Y - this.m_StartPoint.Y);
            this.m_curDraw.SetBound(bound);

            Rectangle _last = this.m_lastBound;
            Rectangle _bound = bound;
            _last.Inflate(2, 2);
            _bound.Inflate(2, 2);

            using (Region invReg = new Region(_last))
            ...{
                invReg.Union(_bound);
                this.Invalidate(invReg);
            }
            this.m_lastBound = bound;
        }
        private void getObj(MouseEventArgs e)
        ...{
            this.m_curDraw = this.m_drawList.GetNear(e.X, e.Y);
            if (this.m_curDraw != null)
            ...{
                this.m_curBound = this.m_curDraw.GetBound();
                this.m_StartPoint = e.Location;
            }
        }
        private void deleteObj()
        ...{
            Rectangle bound = this.m_curDraw.GetBound();
            this.m_drawList.Remove(this.m_curDraw);
            this.m_curDraw = null;
            bound.Inflate(2, 2);
            this.Invalidate(bound);
        }
    }
}

C# WinForm绘图相关相关推荐

  1. 【QT 5 学习笔记-学习绘图相关+画线图形等+绘图事件+基础学习(1)】

    [QT 5 学习笔记-学习绘图相关+画线图形等+绘图事件+基础学习(1)] 1.说明 2.实验环境 3.参照学习链接 4.自己的学习与理解 5.学习与实践代码. (1)建立基础工程. (2)加入绘图事 ...

  2. 计算机辅助相关的,计算机辅助绘图相关的论文

    计算机辅助绘图是环境艺术设计和建筑装饰设计教学的重要辅助手段.下面是学习啦小编给大家推荐的计算机辅助绘图相关的论文,希望大家喜欢! 计算机辅助绘图相关的论文篇一 <计算机辅助设计与AutoCAD ...

  3. 【QT 5 学习笔记-学习绘图相关+画图形图片等+绘图设备+基础学习(2)】

    [QT 5 学习笔记-学习绘图相关+画图形图片等+绘图设备+基础学习(2)] 1.说明 2.实验环境 3.参照连接 4.自己的学习与理解 5.学习与实践代码 (1)移动图片测试实验 (1)继续之前的工 ...

  4. R包corrplot绘图相关系数矩阵

    今天分享一个相关分析可视化实战! 之前我们分享了关于相关分析的原理,还有ggcorrplot包的使用. 相关性分析方法基础:Spearman.Kendall和Pearson R相关矩阵可视化包ggco ...

  5. R画月亮阴晴圆缺:corrplot绘图相关系数矩阵

    今天是十五元宵节,即是和家人团聚的机会,也是赏月的好日子. 但作为科研汪的我,在狗年应更加努力,争取在狗年旺旺,从加班狗中脱颖而出. 分享一个相关分析可视化实战,祝大家元宵节快乐! 先给大家送一个我画 ...

  6. Winform datagridview相关操作

    datagridview显示行号的2种方法: 方法一: 网上最常见的做法是用DataGridView的RowPostPaint事件在RowHeaderCell中绘制行号: privatevoiddat ...

  7. 少儿编程:C++绘图相关书籍篇

    1.魔法学院的奇幻之旅:用GoC编程绘图.基础篇(2017.01) 2.青少年C++趣味入门--2017-04-01 https://study.163.com/course/introduction ...

  8. matplotlib绘图相关

    连续画图,清除上一个 plt.cla() 设置标签 plt.xlabel('章节', fontproperties='SimHei', fontsize=15) plt.ylabel('次数', fo ...

  9. Stata绘图相关问题

    1.改变绘图区域的纵横比 graph command.....,aspectratio(0.5) 2. 时间格式的X轴刻度间距设置 graph command....,xlable(2000(1)20 ...

最新文章

  1. 华南农业大学在Annual Review of Microbiology发表三篇综述文章
  2. 统计_statistics_不同的人_大样本_分析_统计方法_useful ?
  3. 用户id可以出现在url中吗_下载Google Drive中的文件
  4. SonarQube上传分析报告失败
  5. gin ajax 获取请求参数,gin请求参数处理
  6. leetcode第21题: 合并两个有序链表
  7. jQuery 的“原型污染”安全漏洞
  8. 爬虫python入门_python爬虫入门教程有哪些?适合的只有这三个
  9. 完美解决HALCON C#编程目标平台冲突问题
  10. SpringMVC核心
  11. UINavigationController 多次连续 Push Pop 问题
  12. Ubuntu16.04 安装国内版火狐浏览器,同步标签
  13. 分享3个超棒的免费wordpress主题: Splus, EMagazine和BAGONG
  14. PMP-PMBOK(第六版)--49个过程ITTO汇总
  15. matlab三次样条插值多项式,三次样条插值多项式matlab
  16. Word论文排版之样式的使用
  17. AndroidQ SystemUI之锁屏加载(上)滑动锁屏
  18. java旋转太极图_如何用CSS纯代码画一个旋转的太极图(附代码)
  19. kaldi运行yesno例程
  20. 设备管理器的蓝牙设备卸载了,找不到蓝牙

热门文章

  1. 洛谷——P2192 HXY玩卡片
  2. 圆角边框(HTML、CSS)
  3. H5中 video 使用border-radius失效解决方法
  4. Java多线程系列 面试题
  5. Spring Cloud Bus + RabbitMq 自动刷新
  6. 前端验证码绘制(canvas)
  7. 「管理数学基础」1.2 矩阵理论:线性映射、线性变换T的矩阵表示
  8. 【操作系统/OS笔记19】数据块缓存
  9. html脚本类型,HTML脚本标记:类型或语言(或省略两者)?
  10. 腾讯优测干货精选| 安卓开发新技能Get -常用必备小工具汇总