绘图(C# winform)

page11
1、新建工程命名为WindowsFormDrawLine,修改窗体的字体为四号。
2、 新建五个Label, Text属性分别为"红”、"绿”、"蓝”,新建五个NumericUpDown
分别命名为 nudAlpha (透明度)、nudWidth (宽度)、nudRed (红)、nudGreen (绿)、nudBlue (蓝), 新建 panel 命名为 pnl DrawLine o
3、 在Form类中添加如下字段。
private Point pStart, pEnd; 〃画线的起始、终止位置
private Graphics g;
private Pen p;
private Color c; private int width;
4、 给Form ()构造函数中添加如下代码,
public Form 1()
(
InitializeComponent();
c = Color. Black;
width = 1; p = new Pen(c, width);
g = pnlDrawLine. CreateGraphi cs();
5、 给 pnl DrawLine 添加 pnl DrawLine MouseDown 事件代码如下: private void pnl_DrawLine_MouseDown(obj ect sender, MouseEventArgs e)
( pStart = new Point(e.X, e.Y);
}
6、 给 pnl DrawLine 添加 pnl_DrawLine_MouseUp 事件代码如下: private void pnl_DrawLine_MouseUp(object sender, MouseEventArgs e)
( pEnd = new Point(e.X, e.Y); g.DrawLine(p, pStart, pEnd);
}
7、 运行程序看结果。
8、 添加一个函数用于修改透明度、宽度、红、绿、蓝的值,代码如下: private void ReDrawLine(obj ect sender, EventArgs e)
(
c = Color.FromArgb((int)nudAlpha. Value, (int)nudRed. Value, (int)nudGreen. Value, (int)nudBlue. Value); width = (int)nudWidth. Value;
p = new Pen(c, width); g.Clear(this.BackColor); g.DrawLine(p, pStart, pEnd);
}
9、 分别添加透明度、宽度、红、绿、蓝的ValueChanged事件代码如下:
private void nudAlpha_ValueChanged(object sender, EventArgs e)
ReDrawLine(sender, e);
private void nudWidth_ValueChanged(obj ect sender, EventArgs e)
(
ReDrawLine(sender, e);
}
private void nudRed_ValueChanged(object sender, EventArgs e)
(
ReDrawLine(sender, e);
}
private void nudGreen_ValueChanged(object sender, EventArgs e)
(
ReDrawLine(sender, e);
}
private void nudBlue_ValueChanged(object sender, EventArgs e)
( ReDrawLine(sender, e);
}
10、运行看结果,此时发现每次都是最后一条线改变,因为ReDrawline每次只对最后一次的值改变。
11、此时由于RGB的每一项值的范围均为0〜255所以。需要将NumericUpDown的范围调整一下。找到Maximum属性将其值调整为255。
12、 由于这里发现每个ValueChanged调用的都是同一个函数所以我们可以将ReDrawLine放入对应的ValueChanged的事件框里。及在右侧 的事件窗口中找到对应NumericUpDown控件的ValueChanged事件,将其名字都改成ReDrawLineo
13、 运行程序演示。
page
1、 新建工程命名为WindowsFormsCoordinateTrans,给窗体添加两个GroupBox, Text值分别改为
“全局变形”、“针对椭圆的局部变形”。添加十个label分别将text值改成“旋转”(两个)、
“缩放:横向”(两个)、“,纵向”(四个)、“平移:横向”(两个)。添加十个NumericUpDown 分别命名为ngRotate (全局旋转角度)、nlRotate (椭圆旋转角度)、ngxScale (横向全局缩放)、 ngyScale (纵向全局缩放)、ngxMove (全局横向平移)、ngyMove (全局纵向平移)、nlxScale (横向椭圆缩放)、nlyScale (纵向椭圆缩放)、nlxMove (椭圆横向平移)、nlyMove (椭圆纵向平移)。
2、 分别将 ngRotate、nlRotate 的 Maximum 改成 360。将 ngxScale> ngyScale、nlxScale、nlyScale 的 Maximum 值改成 2, Increment 改成 0.1, DecimalPlaces 改成 1。
3、 添加如下字段,用于绘图。
private Graphics g; 〃声明绘图对象
private Pen p; 〃声明钢笔对象
private Rectangle recti, rect2; 〃声明两个矩形区域
private float angle, langle; 〃保存全局旋转和局部旋转的角度
private float dx, dy, Idx, Idy; 〃保存全局缩放或局部缩放的比例 private float mx, my, Imx, Imy; 〃保存全局平移或局部平移的分量
4、 在Form的构造函数中添加如下代码。
public Form 1()
{
InitializeComponent();
g = this.CreateGraphics();
p = new Pen(Color.Blue, 3);
recti = new Rectangle(0, 0, 200, 100);
rect2 = new Rectangle(250, 0, 100, 100);
angle = 0; langle = 0;
dx = 1; dy = 1; Idx = 1; Idy = 1; mx = 0; my = 0; Imx = 0; Imy = 0;
}
5、给Form添加Paint函数,代码如下。
private void Form 1 _Paint(obj ect sender, PaintEventArgs e)
{ —
g = this.CreateGraphics(); 〃 创建绘画对象 g.Clear(this.BackColor); 〃清除原来绘图 g.RotateTransfbrm(angle); 〃启用全局旋转变形 g.ScaleTransform(dx, dy); 〃启用全局缩放变形
g.TranslateTransform(mx, my); 〃启用全局平移变形
GraphicsPath gp = new GraphicsPath(); 〃创建绘图路径对象 gp.AddEllipse(rectl); 〃指定在第一个矩形区域中绘制椭圆
Matrix m = new Matrix(); 〃创建矩阵对象
float r = Convert.ToSingle(nlRotate. Value);
m.Rotate®; 〃设置局部旋转变形的角度
m.Scale(ldx, Idy); 〃设置局部缩放变形的比例 m.Translate(lmx, Imy); 〃设置局部平移量 gp.Transform(m); 〃将局部变形矩阵应用到绘图路径
g.DrawPath(p, gp); 〃根据绘图路径的要求绘图 g.DrawRectangle(p, rect2); 〃绘制矩形
6、添加 using System.Drawing.Drawing2D;
7、 运行代码。
8、 给NumericUpDown添加代码,如下。
private void ngRotate_ValueChanged(obj ect sender, EventArgs e) { —
angle = Convert. ToSingle(ngRotate. Value); this.Refresh();
}
private void nlRotate_ValueChanged(obj ect sender, EventArgs e) { —
langle = Convert.ToSingle(nlRotate. Value); this.Refresh();
}
private void ngxScale_ValueChanged(object sender, EventArgs e) { —
dx = Convert. ToSingle(ngxScale. Value);
this.Refresh();
private void ngyScale_ValueChanged(object sender, EventArgs e) dy = Convert. ToSingle(ngyScale. Value); this.Refresh();
}
private void ngxMove_ValueChanged(obj ect sender, EventArgs e)
{ —
mx = Convert.ToSingle(ngxMove. Value); this.Refresh();
}
private void ngyMove_ValueChanged(obj ect sender, EventArgs e)
{ —
my = Convert.ToSingle(ngyMove. Value); this.Refresh();
}
private void nlxScale_ValueChanged(object sender, EventArgs e)
{ —
Idx = Convert.ToSingle(nlxScale. Value); this.Refresh();
}
private void nlyScale_ValueChanged(object sender, EventArgs e)
{ —
Idy = Convert.ToSingle(nlyScale. Value); this.Refresh();
private void nlxMove_ValueChanged(obj ect sender, EventArgs e) {
Imx = Convert. ToSingle(nlxMove. Value); this.Refresh();
}
private void nlyMove_ValueChanged(obj ect sender, EventArgs e) {
Imy = Convert. ToSingle(nlyMove. Value);
this.Refresh();
9、执行代码。
1、新建工程命名为 WindowsFormsDiamond□
2、 给Form添加load事件,代码如下:
private void Form 1 _Load(obj ect sender, EventArgs e) { —
this.Width= 1050;
this. Height = 1050;
}
3、 给fbrm添加paint事件代码如下:
private void Form 1 _Paint(obj ect sender, PaintEventArgs e) { —
int n = 31; //n=23~31
double t;
int[] x = new int[50];
int[] y = new int[50];
int xO = 500, yO = 500;
int r = 500; //r= 100-200
t = 6.28318/n;
for (int i = 0; i < n; i++)
{
x[i] = (int) (xO + r * Math.Cos(i * t));
y[i] = (int) (yO + r * Math.Sin(i * t));
}
for (int i = 0; i <= n - 2; i++)
{
for (int j = i + 1; j <= n - 1; j++)
e.Graphics.DrawLine(new Pen(Color.Red, 1), new Point(x[i], y[i]), new Point(x[j], y[j]));
4、分别在使用和不适用Form的doublebuffer属性下运行该程序。
1、创建工程命名为 WindowsFormsDoubleBF□
2、 给窗体添加formLoad事件。代码如下:
private void Forml_Load(object sender, EventArgs e)
{ —
this.SetStyle(ControlStyles.ResizeRedraw, true); this.ClientSize = new System.Drawing.Size(300, 300); this.Text = “Double Buffer show”;
}
3、 给窗体添加方法,用于画蜘蛛网线。代码如下:
private void LineDrawRoutine(Graphics g, Pen p) {
float width = ClientRectangle.Width;
float height = ClientRectangle.Height;
float xDelta = width / LINEFREQ;
float yDelta = height / LINEFREQ;
for (int i = 0; i< LINEFREQ; i++)
{
g.DrawLine(p, 0, height - (yDelta * i), xDelta * i, 0); }
}
4、 给窗体添加静态字段。用于表示绘制蜘蛛网线的条数。
const float LINEFREQ= 10;
5、 给窗体添加formPaint事件。代码如下:
private void Form 1 _Paint(obj ect sender, PaintEventArgs e)
{
〃未采用双缓冲技术直接画线
Graphics g = e.Graphics;
Pen bluePen = new Pen(Color.Blue); LineDrawRoutine(g, bluePen);
}
6、 运行代码。分别将LINEFREQ的值以10、100、500进行测试。
7、 给FormPaint添加代码,代码如下:
private void Form 1 _Paint(obj ect sender, PaintEventArgs e)
{
〃未采用双缓冲技术直接画线
//Graphics g = e.Graphics;
//Pen bluePen = new Pen(Color.Blue);
//LineDrawRoutine(g, bluePen);
〃采用双缓冲技术
Graphics g = e.Graphics;
Pen bluePen = new Pen(Color.Blue);
〃将客户区的内容画到bitmapGraphics中去
Bitmap localBitmap = new Bitmap(ClientRectangle.Width, ClientRectangle.Height); Graphics bitmapGraphics = Graphics.Fromlmage(localBitmap);
//Set the SmoothingMode property to smooth the line.
〃使画线平滑
bitmapGraphics. SmoothingMode = System.Drawing.Drawing2D. SmoothingMode. Anti Alias; bitmapGraphics.Clear(BackColor);
〃在bitmapGraphics中画蜘蛛网线
LineDrawRoutine(bitmapGraphics, bluePen);
〃将bitmapGraohics中的绘图在窗体的clientRectangle中显示出来 g.DrawImage(localBitmap, 0, 0);
〃释放资源
bitmapGraphics.Dispose();
bluePen.Dispose。;
localBitmap.Dispose。;
8、 运行代码。分别将LINEFREQ的值以10、100、500进行测试。和前面的非双缓冲进行比较。
9、 将Forml的DoubleBuffer属性改成True,运行代码分别演示LINEFREQ的值以10、100、500的情况。与前面 的非双缓冲,和函数实现的双缓冲进行对比。
10、 在Forml的DoubleBuffer属性为True的时候将LINEFREQ改成1000进行测试。
page
1、 新建工程命名为WindowsFormsDrawText□给窗体添加一个label,将其Text属性设为“请输入文本”。添加四个Button,分别命名为btnFont、 btnStartColor、btnEndColor> btnDraw,分别将Text属性设为“设置字体”、“起始颜色”、“终止颜色”、“绘制文本气 添加一个textBox命名 为 txtSource,添加一个 panel 命名为 pnlShow。添加一个 FontDialog 命名为 dlgFont, 一个 ColorDialog 命名为 dlgColor。
2、 将 pnl 的 Border Style 设为 Fixed3D。
3、 修改窗体的Font为小三调整其他空间的大小和位置。
4、 运行程序。
5、 给btnFont添加Click事件,代码如下。
private void btnFont_Click(obj ect sender, EventArgs e)
{
if (dlgFont.ShowDialog() == DialogResult.OK)
{
font = dlgFont.Font;
}
}
6、 给 Form 类添加 fbnt 字段。Font font;
7、 给btnStartColor添加click事件,代码如下。
private void btnStartColor_Click(object sender, EventArgs e)
{
if (dlgColor. ShowDialog() == DialogResult.OK)
{
startColor = dlgColor. Color;
8、给 Form 类添加 startColor 字段。Color startColor;
9、给btnEndColor添加click事件,代码如下。 private void btnEndColor_Click(obj ect sender, EventArgs e)
{ —
if (dlgColor. ShowDialog() == DialogResult.OK) {
endColor = dlgColor.Color;
10、 给 Form 类添加 endColor 字段。 Color endColor;
11、 给btnDrawText添加click事件,代码如下。
private void btnDraw_Click(object sender, EventArgs e) { —
pnlShow.Refresh();
}
12、 给pnlShow添加Paint事件。代码如下。
private void pnlShow_Paint(obj ect sender, PaintEventArgs e) { —
g = e.Graphics;
LinearGradientBrush IgBrush = new
LinearGradientMode.Horizontal);
StringFormat format = new StringFormat();
format. Alignment = StringAlignment.Center;
// format. F ormatF lags = StringFormatFlags.DirectionRightToLeft;
g.DrawString(txtSource.Text, font, IgBrush, pnlShow.ClientRectangle, format);
}
14、给 Form 类添加 Graphics 字段(实例)Graphics g;
page17
1、新建工程命名为 WindowsFormsDrawTool□
2、 在工程中添加 menuStrip、toolStrip、openFileDialog、saveFileDialog、ColorDialogo
3、 添加菜单项“文件”,“颜色”。添加“文件”的子项“打开”、“新建”、“保存”、“退出”。
4、 给toolStrip添加“铅笔”、“直线”、“矩形”、“椭圆”、“文字”、“橡皮”栏。
5、 只有当“文件”中的“打开”、“新建”返回成功时,才可以进行图形的绘制,所以可在FormLoad函数中可将toolStripl设成 不可用,也可以直接修改toolStripl的Enabled属性。这里将toolStripl的Enabled属性设成False。
6、 修改menuStrip> toolStrip的Font属性,改字体为三号。
7、 给“文件”的“打开”添加代码。
private void 打开 ToolStripMenuItem_Click(object sender, EventArgs e)
{ —
openFileDialogl.Filter = "Image Files(.bmp;.wm£*.ico;.cur;.jgp)|.bmp;.wm£*.ico;.cur;.jpg”;
openFileDialogl. Multiselect = false;
if (openFileDialogl. ShowDialog() == DialogResult.OK)
{
〃修改窗口标题
this.Text = “MyDraw\t” + openFileDialogl. FileName;
editFileName = openFileDialogl.FileName;
thelmage = Image.FromFile(openFileDialogl.FileName);
Graphics g = this.CreateGraphics();
g.DrawImage(theImage, this.ClientRectangle);
ig = Graphics. Fromlmage(thelmage);
ig.DrawImage(theImage, this.ClientRectangle);
//ToolBar可以使用了 toolStripl.Enabled = true;
}
}
8、 添加过程中给Forml类添加字段。这里其它方法会对打开的文件进行操作,所以添加该字段。
〃当前编辑的文件名
private string editFileName;
〃进行操作的位图
private Image thelmage;
〃绘制位图的Graphics实例
private Graphics ig;
9、 给“颜色”添加代码。
private void 颜色 ToolStripMenuItem_Click(object sender, EventArgs e)
{ —
if (colorDialogl. ShowDialog() == DialogResult.OK)
{
fbreColor = colorDialogl .Color;
}
}
10、 此时用到foreColor来指定图形的颜色。需要新添加个字段。
〃绘图使用的色彩
private Color fbreColor = Color.Black;
11、 执行程序演示。
12、 这里需要若干种绘图的形式“铅笔”、“直线”、“矩形”、“椭圆”、 枚举型的字段来确定当前的绘图形式。
13、 添加枚举型字段。如下。drawTool用于确定当前的绘图形式。
private enum drawTools
{
Pen = 0, Line, Ellipse, Rectangle, String, Rubber, None
};
〃当前使用的工具
private drawTools drawTool = drawTools.None;
14、 分别给toolStripl中的各个项添加代码。如下。
private void toolStripButtonl_Click(object sender, EventArgs e) {
drawTool = drawTools. Pen;
}
private void toolStripButton2_Click(object sender, EventArgs e)
{ — drawTool = drawTools.Line;
}
private void toolStripButton3_Click(object sender, EventArgs e)
{ —
drawTool = drawTools.Rectangle;
private void toolStripButton4_Click(object sender, EventArgs e)
{ — drawTool = drawTools. Ellipse;
}
private void toolStripButton5_Click(object sender, EventArgs e)
{ — drawTool = drawTools. String;
}
private void toolStripButton6_Click(object sender, EventArgs e)
{ — drawTool = drawTools.Rubber;
}
15、给“新建”添加代码。如下。 private void 新建 ToolStripMenuItem_Click(object sender, EventArgs e)
{ —
Graphics g = this.CreateGraphics();
g.Clear(backColor); toolStripl.Enabled = true;
〃创建一个Bitmap thelmage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height); editFileName ="新建文件”;
〃修改窗口标题
this.Text = “MyDraw\t” + editFileName;
ig = Graphics. Fromlmage(thelmage);
ig.Clear(backColor);
16、 添加字段backColor用于存放背景颜色。如下。
private Color backColor = Color. White;
17、 给“保存”添加代码。如下。
private void 保存 ToolStripMenuItem_Click(object sender, EventArgs e)
{ —
saveFileDialogl.Filter =“图像(.bmp)|.bmp”; saveFileDialogl.FileName = editFileName;
if (saveFileDialogl. ShowDialog() == DialogResult.OK)
{
theImage.Save(saveFileDialogl.FileName, ImageFormat.Bmp);
this.Text = “MyDraw\t” + saveFileDialogl.FileName;
editFileName = saveFileDialogl.FileName;
}
}
18、 这里使用了 ImageFormat.Bmp 所以需要添加 using System.Drawing.Imaging;
19、 给“退出”添加代码。如下。
private void 退出 ToolStripMenuItem_Click(object sender, EventArgs e)
{
Applicati on. E xit();
}
20、 添加开始绘图的代码,即鼠标左键按下的事件。此时给Forml的MouseDown事件添加代码。此时只讨论直线。
private void Forml_MouseDown(object sender, MouseEventArgs e)
if (e.Button == MouseButtons.Left) 〃如果是左键按下则做 {
startPoint = new Point(e.X, e.Y);
oldPoint = new Point(e.X, e.Y);
21、 此时需要添加开始画图的点,和结束画图的点,添加两个字段。如下。
〃绘图时记录鼠标的位置
private Point startPoint, oldPoint;
22、 添加绘图结束的代码,即鼠标抬起的事件代码。此时给Forml的MouseUp事件添加代码。
private void Forml_MouseUp(object sender, MouseEventArgs e) { —
Graphics g = this.CreateGraphics();
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
}
23、 此时发现只能实现鼠标抬起时显示所画的直线。如果想在鼠标移动的过程中显示曲线则需要添加MouseMove事件。 即边移动边画线。添加代码如下。
private void Forml_MouseMove(object sender, MouseEventArgs e) { —
Graphics g;
g = this.CreateGraphics();
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));

24、此时执行代码发现一片黑连线的情况如下图所示。

25、此时我们需要加个开关,即当鼠标按下时才开始执行MouseMove事件否则不做。代码如下。
private void Forml_MouseMove(object sender, MouseEventArgs e)
{
Graphics g;
g = this.CreateGraphics();
if (isDrawing)
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
26、 添加字段isDrawingo代码如下。
〃布尔型变量,是否正在绘图
private bool isDrawing = false;
27、 此时执行代码仍然无法解决问题。不从起点开始了但是仍然无法消除画线移动时产生的痕迹。

28、此时可以采用刷新解决问题。给Forml添加Paint事件。代码如下。 private void Form 1 _Paint(obj ect sender, PaintEventArgs e)
{ —
〃将Image中保存的图像,绘制出来
Graphics g = this.CreateGraphics();
if (thelmage != null)
{
g.Clear(Color. White);
g.DrawImage(theImage, this.ClientRectangle);
29、给MouseMove添加如下代码。
private void Forml_MouseMove(object sender, MouseEventArgs e)
{
Graphics g;
g = this.CreateGraphics();
if (isDrawing)
{
this.Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
}
}
30、 执行程序,发现仍然没有解决问题,此时点击“新建”再次画直线,发现问题解决。原因为thelmage需要通过“新建”赋值。
31、 此时绘图的基本步骤就完成了。现在解决开始运行程序就能直接画线的问题。只需要在MouseMove和MouseUp中加入代码判断 是否有枚举型字段中的值选中即可。给MouseMove和MouseUp添加代码。代码如下。
private void Forml_MouseUp(object sender, MouseEventArgs e)
isDrawing = false;
Graphics g = this.CreateGraphics();
switch (drawTool)
{
case drawTools.Line:
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y)); break;
private void Forml_MouseMove(object sender, MouseEventArgs e)
{ —
Graphics g;
g = this.CreateGraphics();
if (isDrawing)
{
switch (drawTool)
{
case drawTools.None:
break;
case drawTools.Line:
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
break;
32、 执行程序点击“直线”发现问题解决。画出了直线。
33、 此时发现画当前直线时会删除以前所画的直线。这是因为绘制直线完成后并没有将该直线付给属于Forml的Graphics实例ig。 所以当再次绘制时,绘制将鼠标移到ToolStrip的其他位置时会发现原来画好的线段没有了。
34、 此时我们不能修改MouseMove的中间过程而是应该修改最终结果即MouseUp□修改MouseUp代码。如下。
private void Forml_MouseUp(object sender, MouseEventArgs e)
{ —
isDrawing = false;
switch (drawTool)
{
case drawTools.Line:
ig.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y)); 〃这里才真正修改了属于 //Forml 的 Graphics 实例 break;
35、其他图形的效果是一样的。首先添加“铅笔”的事件。由于它没有中间拖动的过程所以是所见即所得。此时只需修改MouseMove 事件代码如下。
private void Forml_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(fbreColor, 1), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(fbreColor, 1), oldPoint, new Point(e.X, e.Y));
oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
case drawTools.Line:
〃首先恢复此次操作之前的图像,然后再添加Line
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
break;
36、添加“矩形”的代码。这里矩形设计MouseMove和MouseUp事件。代码如下。
private void Forml_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(fbreColor, 1), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(fbreColor, 1), oldPoint, new Point(e.X, e.Y)); oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
case drawTools.Line:
〃首先恢复此次操作之前的图像,然后再添加Line
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
break;
case drawTools.Rectangle:
〃首先恢复此次操作之前的图像,然后再添加Rectangle
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawRectangle(new Pen(fbreColor, 1), startPoint.X, startPoint.X e.X - startPoint.X, e.Y - startPoint. Y); break;
private void Forml_MouseUp(object sender, MouseEventArgs e) { —
isDrawing = false;
switch (drawTool)
case drawTools.Line:
ig.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y)); break;
case drawTools.Rectangle:
ig.DrawRectangle(new Pen(fbreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint. Y); break;
37、添加“椭圆形”的代码。这里矩形设计MouseMove和MouseUp事件。代码如下。
private void Forml_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(fbreColor, 1), oldPoint, new Point(e.X, e.Y)); ig.DrawLine(new Pen(fbreColor, 1), oldPoint, new Point(e.X, e.Y)); oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
case drawTools.Line:
〃首先恢复此次操作之前的图像,然后再添加Line
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y));
break;
case drawTools.Rectangle:
〃首先恢复此次操作之前的图像,然后再添加Rectangle
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawRectangle(new Pen(fbreColor, 1), startPoint.X, startPoint.X e.X - startPoint.X, e.Y - startPoint. Y); break;
case drawTools.Ellipse:
〃首先恢复此次操作之前的图像,然后再添加Ellipse
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawEllipse(new Pen(fbreColor, 1), startPoint.X, startPoint.^ e.X - startPoint.X, e.Y - startPoint.Y); break;
private void Forml_MouseUp(object sender, MouseEventArgs e)
{
isDrawing = false;
switch (drawTool)
{
case drawTools.Line:
ig.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y)); break;
case drawTools.Rectangle:
ig.DrawRectangle(new Pen(fbreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint. Y); break;
case drawTools.Ellipse:
ig.DrawEllipse(new Pen(fbreColor, 1), startPoint.X, startPoint.X e.X - startPoint.X, e.Y - startPoint.Y); break;
}
}
38、这里文字不需要拖动,所以只需在case语句中空白即可。添加“橡皮”的代码,“橡皮”这里可以理解成用 白色绘制粗线将原有图形盖住。代码如下。
private void Forml_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(fbreColor, 1), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(fbreColor, 1), oldPoint, new Point(e.X, e.Y)); oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
case drawTools.Line:
〃首先恢复此次操作之前的图像,然后再添加Line
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawLine(new Pen(fbreColor, 1), startPoint, new Point(e.X, e.Y)); break;
case drawTools.Rectangle:
〃首先恢复此次操作之前的图像,然后再添加Rectangle
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
g.DrawRectangle(new Pen(fbreColor, 1), startPoint.X, startPoint.X e.X - startPoint.X, e.Y - startPoint. Y); break;
case drawTools.Ellipse:
〃首先恢复此次操作之前的图像,然后再添加Ellipse
this. Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle)); g.DrawEllipse(new Pen(fbreColor, 1), startPoint.X, startPoint.^ e.X - startPoint.X, e.Y - startPoint.Y); break;
case drawTools. String: break;
case drawTools.Rubber:
〃用背景色绘制宽线段
g.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));
ig.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));
oldPoint.X = e.X;
oldPoint.Y = e.Y;
break;
39、如果点击文字,则在窗体上显示一个输入框,将文字输入进去,然后打印。
40、 新建一个窗体,命名为Form_Text将其FormBorder Style改成None,添加一个textbox到窗体。将窗体改成和Textbox同样大小。
41、 修改 textBoxl 的 Modifiers 属性为 Public。
42、 此时执行程序发现Form Text无法关闭。这时需要给添加KeyPress事件。代码如下。
private void textBoxl_KeyPress(object sender, KeyPressEventArgs e)
{ —
〃当输入回车时,关闭模式对话窗体
if (e. KeyChar == (char) 13)
{ this.DialogResult = DialogResult.OK;
}
}
43、 执行代码演示之。
page
1、 新建工程命名为 WindowsFormsRectangleRotate»给窗体添加pictureBox控件
命名为pictureBoxl,将其背景颜色BackColor属性改成黄色。添加timer控件命名为 timer 1。
2、 添加Form_Load()代码,如下。
private void Form 1 _Load(obj ect sender, EventArgs e) { —
//pictureBoxl.BackColor = Color. White;
//pictureBoxl.Dock = DockStyle.Fill;
timer 1. Interval =10; timerl.Enabled = true;
}
3、 给pictureBoxl添加Paint事件,代码如下。
private void pictureBoxl_Paint(object sender, PaintEventArgs e)
{
int width = 40;
int height = 80;
int x = (pictureBoxl.Width - width) / 2;
int y = (pictureBoxl.Height - height) / 2;
e.Graphics.TranslateTransfbrm(x, y);
e.Graphics.RotateTransfbrm(angle);
angle += 10;
e.Graphics.DrawRectangle(new Pen(Color.Black, 2), new Rectangle(O - width / 2, 0 - height / 2, width, height-20));
4、 给Form添加字段angle□
private float angle = 0;
5、 给timer添加Tick事件,代码如下。
private void timerl_Tick(object sender, EventArgs e) {
pictureBoxl.Invalidate。; pictureBoxl.Update。;
}
6、 执行代码。
7、 给窗体添加Paint事件。
private void Form 1 _Paint(obj ect sender, PaintEventArgs e) { —
int width = 40;
int height = 80;
int x = (this.Width - width) / 2;
int y = (this.Height - height) / 2; this.CreateGraphics().Clear(BackColor);
e.Graphics.TranslateTransfbrm(x, y);
e.Graphics.RotateTransfbrm(angle);
angle += 10;
e.Graphics.DrawRectangle(new Pen(Color.Black, 2), new Rectangle(0 - width / 2, 0 - height / 2, width, height));
8、在timerl Tick中添加代码。 private void timerl_Tick(object sender, EventArgs e)
{ —
pictureBoxl.Invalidate。;
pictureBoxl.Update。;
this.Form 1 _Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));
9、执行代码。
page
1、 新建工程命名为WindowsFormsRotatePic,给工程添加按钮命名为btnRotate, Text属性 命名为旋转图片。
2、 给Button添加click事件,代码如下:
private void btnRotate_Click(object sender, EventArgs e)
{
Graphics graphics = this.CreateGraphics(); graphics.Clear(Color. White);
〃装入图片
Bitmap image = new Bitmap(“Tile.jpg”);
〃获取当前窗口的中心点
Rectangle rect = new Rectangle(O, 0, this. ClientSize. Width, this.ClientSize.Height); PointF center = new PointF(rect.Width / 2, rect.Height / 2);
float offsetX = 0;
float offsetY = 0;
offsetX = center.X - image.Width / 2; offsetY = center.Y - image.Height / 2;
〃构造图片显示区域:让图片的中心点与窗口的中心点一致
RectangleF picRect = new RectangleF(offsetX, offset^ image.Width, image.Height); PointF Pcenter = new PointF(picRect.X + picRect.Width / 2,
picRect.Y + picRect.Height/ 2);
〃让图片绕中心旋转一周
〃算法的思想,1、首先使graphics所代表的绘图区域,即clientRectangle的坐标原点; // 2、使graphics所代表的绘图区域旋转i个角度。(这里Rotate的旋转是
// 根据原点旋转的,其他例子可能使用Rotate (x,y)的方法);

3、 恢复坐标原点为旋转后的clientRectangle区域的左上角(注意是旋 转后的 clientRectangle 区)
4、 绘制需要绘制的图片并延时;
5、 重置所有graphics的转换。(这里如果不重置转换,则每次都会根 据旋转后的graphics再旋转i度,所以必须回到未曾旋转过的状态才能 进入下一次旋转i度)。
for (int i = 0; i < 361; i ++)
{
//绘图平面以图片的中心点旋转
//graphics. Clear(Color. White);
graphics.TranslateTransfbrm(Pcenter.X, Pcenter.Y);
graphics.RotateTransfbrm(i);
〃恢复绘图平面在水平和垂直方向的平移
graphics.TranslateTransfbrm(-Pcenter.X, -Pcenter.Y);
〃绘制图片并延时
graphics.DrawImage(image,new Point (0,0));//加入此语句说明实际旋转的是整个Client区域 graphics.Drawlmage(image, picRect);
Thread. Sleep( 100);
〃重置绘图平面的所有变换,这里说明是针对当前旋转再旋转的例子,可以去掉本句话再演示。 graphics.ResetTransfbrm();
3、这里的Tile.jpg图片为己经放入Debug中的指定文件,可以自行截图放在该文件夹中。
page
1、新建工程命名为 WindowsFormsSmoothingMode □
2、给Forml添加paint事件,代码如下:
private void Form 1 _Paint(obj ect sender, PaintEventArgs e)
{ —
// Set the SmoothingMode property to smooth the line.
e.Graphics. SmoothingMode = System.Drawing.Drawing2D. SmoothingMode. AntiAlias;
// Create a new Pen object.
Pen greenPen = new Pen(Color.Green);
// Set the width to 6.
greenPen.Width = 6.OF;
// Set the DashCap to round.
greenPen. DashCap = System. Drawing. Drawing2D. DashCap. Round;
// Create a custom dash pattern. line, blank, line, blank
greenPen.DashPattem = new float[] { 4.0F, 2.OF, 1.0F, 3.OF };
// Draw a line.
e.Graphics.DrawLine(greenPen, 20.OF, 20.OF, 100.OF, 240.OF);
// Change the SmoothingMode to none.
e.Graphics. SmoothingMode = System.Drawing.Drawing2D. SmoothingMode.None;
// Draw another line.
e.Graphics.DrawLine(greenPen, 100.OF, 240.OF, 160.OF, 20.OF);
// Dispose of the custom pen. greenPen.Dispose();
}
3、 分别修改 greenPen.DashPattern = newfloat[] { 4.0F, 2.OF, 1.0F, 3.OF };中的各个值,观察虚线 的变化情况。
4、 执行程序,将图形截图。然后再Windows图片查看器中打开,放大到足够大,观察图形的情况。

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

次郎不小

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值