版权声明:本文为博主原创文章,未经博主允许不得转载。

欢迎大家提出意见,一起讨论!

转载请标明是引用于 http://blog.csdn.net/chenyujing1234

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

实现过程:

(1) 新建窗体应用程序

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

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

(3)程序代码。

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

private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
g.Clear(backColor);
toolStrip1.Enabled = true;
//创建一个Bitmap
theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
editFileName = "新建文件";
//修改窗口标题
this.Text = "MyDraw\t" + editFileName;
ig = Graphics.FromImage(theImage);
ig.Clear(backColor);
}

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

private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.Multiselect = false;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//修改窗口标题
this.Text = "MyDraw\t" + openFileDialog1.FileName;
editFileName = openFileDialog1.FileName;
theImage = Image.FromFile(openFileDialog1.FileName);
Graphics g = this.CreateGraphics();
g.DrawImage(theImage, this.ClientRectangle);
ig = Graphics.FromImage(theImage);
ig.DrawImage(theImage, this.ClientRectangle);
//ToolBar可以使用了
toolStrip1.Enabled = true;
}
}

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

private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1.Filter = "图像(*.bmp)|*.bmp";
saveFileDialog1.FileName = editFileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
theImage.Save(saveFileDialog1.FileName, ImageFormat.Bmp);
this.Text = "MyDraw\t" + saveFileDialog1.FileName;
editFileName = saveFileDialog1.FileName;
}
}

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

private void Form1_Paint(object sender, PaintEventArgs e)
{
//将Image中保存的图像,绘制出来
Graphics g = this.CreateGraphics();
if (theImage != null)
{
g.Clear(Color.White);
g.DrawImage(theImage, this.ClientRectangle);
}
}

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

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

把FormBorderStyle属性改为 None;

把Modifiers的属性改为 Public

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

private void Frm_Main_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
//如果选择文字输入,则打开strInput窗体
if (drawTool == drawTools.String)
{
Frm_Text inputBox = new Frm_Text();
inputBox.StartPosition = FormStartPosition.CenterParent;
if (inputBox.ShowDialog() == DialogResult.OK)
{
Graphics g = this.CreateGraphics();
Font theFont = this.Font;
g.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);
ig.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);
}
}
//如果开始绘制,则开始记录鼠标位置
else if ((isDrawing = !isDrawing) == true)
{
startPoint = new Point(e.X, e.Y);
oldPoint = new Point(e.X, e.Y);
}
}
}

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

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Graphics g;
g = this.CreateGraphics(); if (isDrawing)
{
switch (drawTool)
{
case drawTools.None:
break;
case drawTools.Pen:
//从上一个点到当前点绘制线段
g.DrawLine(new Pen(foreColor, ), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(foreColor, ), oldPoint, new Point(e.X, e.Y));
oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
case drawTools.Line:
//首先恢复此次操作之前的图像,然后再添加Line
this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawLine(new Pen(foreColor, ), startPoint, new Point(e.X, e.Y));
break;
case drawTools.Ellipse:
//首先恢复此次操作之前的图像,然后再添加Ellipse
this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawEllipse(new Pen(foreColor, ), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
break;
case drawTools.Rectangle:
//首先恢复此次操作之前的图像,然后再添加Rectangle
this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawRectangle(new Pen(foreColor, ), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
break;
case drawTools.String:
break;
case drawTools.Rubber:
//用背景色绘制宽线段
g.DrawLine(new Pen(backColor, ), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(backColor, ), oldPoint, new Point(e.X, e.Y));
oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
}
}
}

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

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
isDrawing = false;
switch (drawTool)
{
case drawTools.Line:
ig.DrawLine(new Pen(foreColor, ), startPoint, new Point(e.X, e.Y));
break;
case drawTools.Ellipse:
ig.DrawEllipse(new Pen(foreColor, ), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
break;
case drawTools.Rectangle:
ig.DrawRectangle(new Pen(foreColor, ), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);
break;
}
}

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

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

这里有两个Graphics:

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

eg:

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

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

它在新建的时候创建:

//创建一个Bitmap
theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
editFileName = "新建文件";
//修改窗口标题
this.Text = "MyDraw\t" + editFileName;
ig = Graphics.FromImage(theImage);
ig.Clear(backColor);

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

private void Frm_Main_Paint(object sender, PaintEventArgs e)
{
//将Image中保存的图像,绘制出来
Graphics g = this.CreateGraphics();
if (theImage != null)
{
g.Clear(Color.White);
g.DrawImage(theImage, this.ClientRectangle);
}
}

在Form1_MouseMove里

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

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

【CITE】C#入门学习-----简单画图程序的更多相关文章

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

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

  2. python基础入门学习简单程序练习

    1.简单的乘法程序 i = 256*256 print('The value of i is', i) 运行结果: The value of i is 65536 2.执行python脚本的两种方式 ...

  3. C#简单画图程序

    实现过程: (1) 新建窗体应用程序 (2) 添加一个MenuScrip控件:添加一个ToolScrip控件. 在ToolScrip控件中对每个单元,要将DisplayStyle属性改为Text (3 ...

  4. 微信小程序开发入门学习(2):小程序的布局

    概述 小程序的布局采用了和Css3中相同的 flex(弹性布局)方式,使用方法也类似(只是属性名不同而已). 水平排列 默认是从左向右水平依次放置组件,从上到下依次放置组件. 任何可视组件都需要使用样 ...

  5. 微信小程序入门学习

    前(che)言(dan): 近几天,微信小程序的内测引起了众多开发人员的热议,很多人都认为这将会成为一大热门,那么好吧,虽然我是一个小白,但这是个新玩意,花点时间稍稍钻研一下也是无妨的,谁让我没有女朋 ...

  6. C#程序入门学习

    前言: C# (C sharp) 是微软对这一问题的解决方案.C#是一种最新的.面向对象的编程语言.它使得程序员可以快速地编写各种基于Microsoft .NET平台的应用程序,Microsoft . ...

  7. Python入门学习:1.变量和简单的数据类型

    python入门学习:1.变量和简单的数据类型 关键点:变量.字符串.数字 1.1 变量的命名和使用1.2 字符串1.3 数字1.4 注释 1.1 变量的命名和使用   变量,顾名思义是一个可变的量, ...

  8. 毕业设计预习:VHDL入门知识学习(一) VHDL程序基本结构

    VHDL入门知识学习(一) VHDL程序基本结构 简介 VHDL程序基本结构 简介 概念: HDL-Hardware Description Language-硬件描述语言-描述硬件电路的功能.信号连 ...

  9. 【转载】salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建

    salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建   VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的 ...

随机推荐

  1. BZOJ 1413 取石子游戏(DP)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1413 题意:n堆石子排成一排.每次只能在两侧的两堆中选择一堆拿.至少拿一个.谁不能操作谁 ...

  2. 【转载】nedmalloc结构分析

    原文:nedmalloc结构分析 nedmalloc是一个跨平台的高性能多线程内存分配库,很多库都使用它,例如:OGRE.现在我们来看看nedmalloc的实现 (以WIN32部分为例)    位操作 ...

  3. Java_GC详解

    Java -- GC 标签(空格分隔): Java 要想深入了解Java的GC(Garbage Collection),我们应该先探寻如下三个问题: What? -- 哪些内存需要回收? When? ...

  4. choco命令

    C:\Users\Administrator>chocoChocolatey v0.10.0 C:\Users\Administrator>choco --version0.10.0 C: ...

  5. application 网站计数器

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  6. Socket&GCDAsyncSocket(异步Socket)

    Socket ********************************************* 简单理解Socket 就是网络连接,可以实现两个点之间的数据通讯. •Socket允许使用长连 ...

  7. Object-C中的排序和Compare陷阱

    来源:http://m.blog.csdn.net/blog/u011883764/38868097 Date : 2015-12-24 一.Compare陷阱 NSString有多个compare相 ...

  8. DataTable字符串类型的数字,按照数字类型排序

    protected void Page_Load(object sender, EventArgs e)     {         DataTable dt = new DataTable();   ...

  9. js求和算法研究

    如果遇到一个试题是这样. function sum(arr){ //求和 } 你会怎么做? 反正我第一反应是这样做. function sum(arr){ var result = 0; for(va ...

  10. oracle的正则表达式

    阅读目录 1.oracle(regular expression)简单介绍 2.oracle正则特殊字符 3.oracle正则字符簇 4.各种操作符的运算优先级 5.模拟测试例子 6.oracle对应 ...