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

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

转载请标明是引用于 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	" + 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	" + 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	" + 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, 1), oldPoint, new Point(e.X, e.Y));  
                ig.DrawLine(new Pen(foreColor, 1), 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, 1), 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, 1), 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, 1), 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, 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;  
        }  
    }  
}  

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

private void Form1_MouseUp(object sender, MouseEventArgs e)  
        {  
            isDrawing = false;  
            switch (drawTool)  
            {  
                case drawTools.Line:  
                    ig.DrawLine(new Pen(foreColor, 1), startPoint, new Point(e.X, e.Y));  
                    break;  
                case drawTools.Ellipse:  
                    ig.DrawEllipse(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);  
                    break;  
                case drawTools.Rectangle:  
                    ig.DrawRectangle(new Pen(foreColor, 1), 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	" + 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里。

原文地址:https://www.cnblogs.com/hardsoftware/p/5715668.html