实现过程:

(1) 新建窗体应用程序

(2) 添加一个MenuScrip控件;添加一个ToolScrip控件。

在ToolScrip控件中对每个单元,要将DisplayStyle属性改为Text

(3)程序代码。

1、新建菜单事件主要用白色清除窗体的背景,从而实现“文件新建”功能

  1. [csharp] view plain copy
  2. private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
  3. {
  4. Graphics g = this.CreateGraphics();
  5. g.Clear(backColor);
  6. toolStrip1.Enabled = true;
  7. //创建一个Bitmap
  8. theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
  9. editFileName = "新建文件";
  10. //修改窗口标题
  11. this.Text = "MyDraw\t" + editFileName;
  12. ig = Graphics.FromImage(theImage);
  13. ig.Clear(backColor);
  14. }

  2、打开事件用于打开“打开文件”对话框,并选择相应的图片,将图片绘制到窗体上.

  1. [csharp] view plain copy
  2. private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
  3. {
  4. openFileDialog1.Multiselect = false;
  5. if (openFileDialog1.ShowDialog() == DialogResult.OK)
  6. {
  7. //修改窗口标题
  8. this.Text = "MyDraw\t" + openFileDialog1.FileName;
  9. editFileName = openFileDialog1.FileName;
  10. theImage = Image.FromFile(openFileDialog1.FileName);
  11. Graphics g = this.CreateGraphics();
  12. g.DrawImage(theImage, this.ClientRectangle);
  13. ig = Graphics.FromImage(theImage);
  14. ig.DrawImage(theImage, this.ClientRectangle);
  15. //ToolBar可以使用了
  16. toolStrip1.Enabled = true;
  17. }
  18. }

  (3) 保存菜单项的Click事件用于将窗体背景保存为BMP格式的图片

  1. [csharp] view plain copy
  2. private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
  3. {
  4. saveFileDialog1.Filter = "图像(*.bmp)|*.bmp";
  5. saveFileDialog1.FileName = editFileName;
  6. if (saveFileDialog1.ShowDialog() == DialogResult.OK)
  7. {
  8. theImage.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
  9. this.Text = "MyDraw\t" + saveFileDialog1.FileName;
  10. editFileName = saveFileDialog1.FileName;
  11. }
  12. }

  (4) 在Paint事件中将Image中保存的图像,绘制出来

  1. [csharp] view plain copy
  2. private void Form1_Paint(object sender, PaintEventArgs e)
  3. {
  4. //将Image中保存的图像,绘制出来
  5. Graphics g = this.CreateGraphics();
  6. if (theImage != null)
  7. {
  8. g.Clear(Color.White);
  9. g.DrawImage(theImage, this.ClientRectangle);
  10. }
  11. }

  

(5)添加Frm_Text.cs文字输入框。

添加一个Window窗体,取名为Frm_Text,然后对窗体的属性修改:

把FormBorderStyle属性改为 None;

把Modifiers的属性改为 Public

(6) 在窗体的MouseDown事件中,如果当前绘制的是字符串,在鼠标的当前位置显示文本框;如果绘制的是图开,设置图形的起始位置。

  1. [cpp] view plain copy
  2. private void Frm_Main_MouseDown(object sender, MouseEventArgs e)
  3. {
  4. if (e.Button == MouseButtons.Left)
  5. {
  6. //如果选择文字输入,则打开strInput窗体
  7. if (drawTool == drawTools.String)
  8. {
  9. Frm_Text inputBox = new Frm_Text();
  10. inputBox.StartPosition = FormStartPosition.CenterParent;
  11. if (inputBox.ShowDialog() == DialogResult.OK)
  12. {
  13. Graphics g = this.CreateGraphics();
  14. Font theFont = this.Font;
  15. g.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);
  16. ig.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);
  17. }
  18. }
  19. //如果开始绘制,则开始记录鼠标位置
  20. else if ((isDrawing = !isDrawing) == true)
  21. {
  22. startPoint = new Point(e.X, e.Y);
  23. oldPoint = new Point(e.X, e.Y);
  24. }
  25. }
  26. }

  (7) 在窗体的MouseMove 事件中,根据鼠标移动的大小绘制指定的图形.

  1. [cpp] view plain copy
  2. private void Form1_MouseMove(object sender, MouseEventArgs e)
  3. {
  4. Graphics g;
  5. g = this.CreateGraphics();
  6.  
  7. if (isDrawing)
  8. {
  9. switch (drawTool)
  10. {
  11. case drawTools.None:
  12. break;
  13. case drawTools.Pen:
  14. //从上一个点到当前点绘制线段
  15. g.DrawLine(new Pen(foreColor, 1), oldPoint, new Point(e.X, e.Y));
  16. ig.DrawLine(new Pen(foreColor, 1), oldPoint, new Point(e.X, e.Y));
  17. oldPoint.X = e.X;
  18. oldPoint.Y = e.Y;
  19. break;
  20. case drawTools.Line:
  21. //首先恢复此次操作之前的图像,然后再添加Line
  22. this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
  23. g.DrawLine(new Pen(foreColor, 1), startPoint, new Point(e.X, e.Y));
  24. break;
  25. case drawTools.Ellipse:
  26. //首先恢复此次操作之前的图像,然后再添加Ellipse
  27. this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
  28. g.DrawEllipse(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
  29. break;
  30. case drawTools.Rectangle:
  31. //首先恢复此次操作之前的图像,然后再添加Rectangle
  32. this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
  33. g.DrawRectangle(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
  34. break;
  35. case drawTools.String:
  36. break;
  37. case drawTools.Rubber:
  38. //用背景色绘制宽线段
  39. g.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));
  40. ig.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));
  41. oldPoint.X = e.X;
  42. oldPoint.Y = e.Y;
  43. break;
  44. }
  45. }
  46. }

  (8) 在窗体的MouseUp事件中,根据用户选择的画笔,绘制直线,椭圆或矩形等指定图形。

  1. [csharp] view plain copy
  2. private void Form1_MouseUp(object sender, MouseEventArgs e)
  3. {
  4. isDrawing = false;
  5. switch (drawTool)
  6. {
  7. case drawTools.Line:
  8. ig.DrawLine(new Pen(foreColor, 1), startPoint, new Point(e.X, e.Y));
  9. break;
  10. case drawTools.Ellipse:
  11. ig.DrawEllipse(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
  12. break;
  13. case drawTools.Rectangle:
  14. ig.DrawRectangle(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
  15. break;
  16. }
  17. }

  

=============================================================================================================

这里解释为什么在拉直线时线会跟着鼠标动,而用选择画笔时移动鼠标就会画出线。

这里有两个Graphics:

(1) 真实的场景graphics.   它它上面画出的画面就是我个看到的画面。

eg:

private void Form1_Paint(object sender, PaintEventArgs e)
             {
                     //将Image中保存的图像,绘制出来
                      Graphics g = this.CreateGraphics();

(2)做为临时存储用的Graphic.

它在新建的时候创建:

  1. [csharp] view plain copy
  2. //创建一个Bitmap
  3. theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
  4. editFileName = "新建文件";
  5. //修改窗口标题
  6. this.Text = "MyDraw\t" + editFileName;
  7. ig = Graphics.FromImage(theImage);
  8. ig.Clear(backColor);

  显示出来: 把theImage显示出来就是把以前保存在ig里的东西显示出来了

  1. [csharp] view plain copy
  2. private void Frm_Main_Paint(object sender, PaintEventArgs e)
  3. {
  4. //将Image中保存的图像,绘制出来
  5. Graphics g = this.CreateGraphics();
  6. if (theImage != null)
  7. {
  8. g.Clear(Color.White);
  9. g.DrawImage(theImage, this.ClientRectangle);
  10. }
  11. }

  

在Form1_MouseMove里

如果是画笔,那么把图像保存到了两个graphic中,这样我们可以看到移动的画,最后也将显示所有画。

如果直线或矩形,那么只先画到第一个graphics里,在鼠标放开时才画到第二个graphic里。

通过本实例了解如何在窗体上绘制各种图形,如矩形、椭圆、线条、文字等。运行效果如下:

C#简单画图程序的更多相关文章

  1. Xamarin开发的一个简单画图程序分享

    最近Xamarin比较火,于是稍微看了下,感觉接触过MVC的都应该能很快上手,还挺有意思,于是忍不住写了个简单的画图程序,之前看帖子有人说装不上或者无法部署,估计我比较幸运,编译完了一次就安装成功了, ...

  2. 【CITE】C#入门学习-----简单画图程序

    版权声明:本文为博主原创文章,未经博主允许不得转载. 欢迎大家提出意见,一起讨论! 转载请标明是引用于 http://blog.csdn.net/chenyujing1234 通过本实例了解如何在窗体 ...

  3. 贪吃蛇—C—基于easyx图形库(下):从画图程序到贪吃蛇【自带穿墙术】

    上节我们用方向控制函数写了个小画图程序,它虽然简单好玩,但我们不应该止步于此.革命尚未成功,同志还需努力. 开始撸代码之前,我们先理清一下思路.和前面画图程序不同,贪吃蛇可以有很多节,可以用一个足够大 ...

  4. 贪吃蛇—C—基于easyx图形库(上):基本控制函数实现 画图程序

    自从学了c语言,就一直想做个游戏,今天将之付之行动,第一次写的特别烂,各种bug:就不贴了.今天网上看了好几个贪吃蛇,重新写了一次,做出来的效果还可以. p.s.  easyx图形库是为了方便图形学教 ...

  5. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

  6. java画图程序_图片用字母画出来_源码发布_版本二

    在上一个版本:java画图程序_图片用字母画出来_源码发布 基础上,增加了图片同比例缩放,使得大像素图片可以很好地显示画在Notepad++中. 项目结构: 运行效果1: 原图:http://imag ...

  7. java画图程序_图片用字母画出来_源码发布

    在之前写了一篇blog:java画图程序_图片用字母画出来 主要是把一些调试的截图发布出来,现在程序调试我认为可以了(当然,你如果还想调试的话,也可以下载源码自己调试). 就把源码发布出来. 项目结构 ...

  8. java画图程序_图片用字母画出来

    最近在研究怎样将图片用字母在文本编辑工具中“画”出来. 你看了这个可能还不知道我想说什么? 我想直接上图,大家一定就知道了 第一张:小猫 原图:http://www.cnblogs.com/hongt ...

  9. (转)Windows Server 2008 默认"照片库查看器" 无法打开图片, 只能用画图程序打开

    1.解决[启用Win2008照片查看器] Win2008 中放了一些图片,本来以为可以象Win7那样直接用“照片查看器”打开,可是Win2008默认竟然是用“画图”打开的,非常不方便. 再仔细一看,“ ...

随机推荐

  1. mysql数值运算符和函数

    mysql> |+------------+1 row in set (0.00 sec) mysql> SELECT FLOOR(3.99);  # 舍1取整+------------- ...

  2. JS算法练习一

    JS算法练习 1.随机生成一个五位以内的数,然后输出该数共有多少位,每位分别是什么? ①.数组添加元素的方式得到位数(数组长度)与值(数组元素) ①.数组添加元素的方式得到位数(数组长度)与值(数组元 ...

  3. Ubuntu18.04下Python Web环境搭建

    Python3的安装与卸载 pip, pip3的安装 Django2.x的安装 mysql的安装及命令行工具mycli的安装 virtualenv及virtualenvwrapper的安装 IPyth ...

  4. react ,ant Design UI中table组件合并单元格并展开详情的问题

    需求:购物车订单列表,如图: 一:单元格合并 遇到这种你会怎么办呢?  单元格合并?  还是其他的方法? 下面是我的处理方式,就是在table 组件的columns上处理,这里拿商品举例,其余的类似, ...

  5. day 7 - 1 集合、copy及基础数据类型汇总

    集合:{},可变的数据类型,他里面的元素必须是不可变的数据类型,无序,不重复.(不重要)集合的书写 set1 = set({1,2,3}) #set2 = {1,2,3,[2,3],{'name':' ...

  6. Linux常用命令(三)查看当前计算机各方面信息

    1.查看cpu: top 2.查看当前linux版本:name -a 查看当前运行的内核版本:cat /pro/version 查看发行版本信息:cat /etc/issue 查看上面所有信息:lsb ...

  7. Android程序破解思路

    Android程序的一般分析与破解流程 1.如何寻找突破口是分析一个程序的关键.错误提示信息左右一般是程序验证逻辑的核心代码. 2.错误提示是android程序的字符串资源,字符串有可能硬编码到源码中 ...

  8. Django学习手册 - ORM sqlit基础数据库操作

    步骤阐述:( splitDB 是Django自带的一个数据库) 1.在APP01 中的 models.py 配置DB信息  userinfo 相当于数据表的表名,而 uname.pwd 相当于 表中的 ...

  9. scrapy基础 之 爬虫入门:先用urllib2来理解爬虫

    1,概念理解 爬虫:抓取和保存网页信息,用户看到的网页实质是由 HTML 代码构成的,爬虫爬来的便是这些内容,通过分析和过滤这些 HTML 代码,实现对图片文字等资源的获取. URL:即统一资源定位符 ...

  10. OVS-----CentOS7上搭建基于Open vSwitch的VxLAN隧道实验

    一.关于VXLAN VXLAN 是 Virtual eXtensible LANs 的缩写,它是对 VLAN 的一个扩展,是非常新的一个 tunnel 技术,在Open vSwitch中应用也非常多. ...