用C#的GDI+来绘图时按下alt后发现绘制的全没了(窗体应用)

用C#的GDI+来绘图时按下alt后发现绘制的全没了(窗体应用)

private void field_MouseDown(object sender, MouseEventArgs e)//用来记录点击鼠标时的指针位置
        {
            //if (type == 2)
            //{
                Brush brush = new SolidBrush(Color.Blue);
                Point[] pts_tmp = new Point[4];
                pts_tmp[0] = new Point(40, 40);
                pts_tmp[1] = new Point(80, 40);
                pts_tmp[2] = new Point(80, 80);
                pts_tmp[3] = new Point(40, 80);
                fill(pts_tmp);
            //}
        }

其中fill如下:

 private void fill(Point[] pts_tmp)
        {
            Brush brush = new SolidBrush(Color.Blue);
            g.FillPolygon(brush, pts_tmp);
        }

g也进行了定义:

```c#
Graphics g;//这个语句是全局定义的

g = this.CreateGraphics();//这个语句是在field_Load执行的

点击按钮后再点击网格中任意一处生成了蓝色的块,效果如下:

img

但如果按下alt键后蓝块就消失了,效果如下:

img

绘制的网格不变,是因为鼠标的点击造成了什么吗?
谢谢

放个picture,在picture里绘制。

绘制的时机不对,在painter中绘制即可。

img

代码已经修改,参照一下代码:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace WindowsForms
{

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            buffer = new Bitmap(this.Width, this.Height);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            //g = this.CreateGraphics();//这个语句是在field_Load执行的
        }


        //Graphics g;//这个语句是全局定义的
        private Bitmap buffer; // 位图对象
        private void Form1_Click(object sender, EventArgs e)
        {

            using (Graphics g = Graphics.FromImage(buffer))
            {
                Brush brush = new SolidBrush(Color.Blue);
                Point[] pts_tmp = new Point[4];
                pts_tmp[0] = new Point(40, 40);
                pts_tmp[1] = new Point(80, 40);
                pts_tmp[2] = new Point(80, 80);
                pts_tmp[3] = new Point(40, 80);
                g.FillPolygon(brush, pts_tmp);
            }

            this.Invalidate();


        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(buffer, 0, 0);
        }
    }
}

你每次鼠标点击时,都调用CreateGraphics()来获取一个新的Graphics对象。
而按下Alt键会刷新窗口,导致之前的Graphics对象失效,所以绘制的内容就没有了

可以使用 GDI+ 画图
非常详细,可以参考下

当窗口最小化或者按Alt建时,Form上的图画都会消失,原来这是因为最小化后还原时窗体要重绘,图画被覆盖消失。
解决方法有两个:一是在窗口Form的Paint事件中重新绘制图画;二是把图画在位图上,然后把位图赋给能显示图片的窗口或控件上。
一. 在窗口Form的Paint事件中重新绘制图画
具体做法就是把你绘图的代码写在Paint事件中
二. 把图画在位图上

重写窗体应用的PreProcessMessage方法来处理Alt键的按下,避免清除绘制的内容

引用chatgpt内容作答:
按下Alt键会触发窗体的系统菜单,这可能导致绘图被清除或隐藏。这是因为在窗体中使用CreateGraphics方法创建的Graphics对象是临时的,并不会持久保存绘图内容。当窗体需要重绘时,原先的绘图内容就会被清除。

为了解决这个问题,你可以使用以下方法之一:

在窗体的Paint事件中进行绘图:将绘图操作移动到窗体的Paint事件处理程序中,这样每次窗体重绘时都会执行绘图操作。你可以在field_Load事件处理程序中注册Paint事件的处理程序,或者直接在窗体的构造函数中添加。

public Form1()
{
    InitializeComponent();
    this.Paint += Form1_Paint;
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    // 在这里进行绘图操作
    Brush brush = new SolidBrush(Color.Blue);
    Point[] pts_tmp = new Point[4];
    pts_tmp[0] = new Point(40, 40);
    pts_tmp[1] = new Point(80, 40);
    pts_tmp[2] = new Point(80, 80);
    pts_tmp[3] = new Point(40, 80);
    e.Graphics.FillPolygon(brush, pts_tmp);
}

使用双缓冲绘图:创建一个临时的Bitmap对象,在其上进行绘图操作,然后将绘制结果复制到窗体的CreateGraphics返回的Graphics对象上。这样可以避免窗体重绘时绘图被清除。

private Bitmap buffer; // 用于双缓冲绘图的位图对象

public Form1()
{
    InitializeComponent();
    buffer = new Bitmap(this.Width, this.Height);
}

private void field_MouseDown(object sender, MouseEventArgs e)
{
    using (Graphics g = Graphics.FromImage(buffer))
    {
        Brush brush = new SolidBrush(Color.Blue);
        Point[] pts_tmp = new Point[4];
        pts_tmp[0] = new Point(40, 40);
        pts_tmp[1] = new Point(80, 40);
        pts_tmp[2] = new Point(80, 80);
        pts_tmp[3] = new Point(40, 80);
        g.FillPolygon(brush, pts_tmp);
    }

    using (Graphics g = this.CreateGraphics())
    {
        g.DrawImage(buffer, 0, 0);
    }
}

使用双缓冲绘图的方法会将绘图内容保存在位图对象中,并在需要时进行绘制,因此按下Alt键时绘图不会被清除。