如何使用 Paint 事件在鼠标坐标处绘制形状

kus*_*kus 1 .net c# graphics paintevent winforms

我最近开始C#明显地编程,并试图做一个简单的WinForms应用程序,它采用鼠标坐标并根据坐标缩放矩形。

我面临的问题是我不知道如何调用使用更多参数的方法(在这种情况下是x,yPaintEventArgs)。或者,我确实知道如何处理PaintEvent.

这是整个代码,因为它很短而且很简单:

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        int x = e.X; 
        int y = e.Y;
        String data = (x.ToString() + " " + y.ToString());
        DrawRect(Something, x, y);
    }

    PaintEventArgs pEventArgs;
    private void Form1_Paint(object sender, PaintEventArgs e)
    {

    }

    public void DrawRect(PaintEventArgs e, int rey, int rex)
    {
        Graphics gr = e.Graphics;
        Pen pen = new Pen(Color.Azure, 4);
        Rectangle rect = new Rectangle(0, 0, rex, rey);
        gr.DrawRectangle(pen, rect);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想打电话给DrawRect()一起绘制矩形方法width,并height根据鼠标的坐标。

那么我如何调用DrawRect()with 坐标和PaintEventArgs

Jim*_*imi 8

在控件的表面上绘图时,您始终使用该Paint控件的事件或覆盖OnPaint自定义/用户控件的方法。
不要试图存储它的Graphics对象:一旦控件失效(重新绘制),它就会变得无效。
使用Graphics对象提供的PaintEventArgs对象。

当需要更复杂的过程来绘制不同的形状时,您可以将e.Graphics对象传递给不同的方法,这些方法将使用此对象执行专门的绘图。


在示例中,每个绘制形状的坐标和其他属性都分配给了一个专门的类DrawingRectangle(这里是一个简化的结构,它可以包含更复杂的功能)。
AList<DrawingRectangle>()存储会话中DrawingRectangle生成的所有对象的引用(直到图形被清除)。

每次MouseDown在控件的表面上生成Left事件时,都会将一个新DrawingRectangle对象添加到列表中。
e.Location被存储既作为DrawingRectangle.StartPoint(即不改变的值)和所述DrawingRectangle.Location:当鼠标指针移动此值将被更新。

当鼠标移动时,e.Location从先前存储的起点坐标中减去当前值。一个简单的计算允许从四面八方绘制形状。
此度量确定矩形的当前大小。

要从绘图中移除 Rectangle,您只需要从 List 和Invalidate()提供绘图表面的 Control 中移除它的引用。
要清除绘图表面,请清除List<DrawingRectangle>()( drawingRects.Clear()) 并调用Invalidate()

这里的其他一些示例:
透明重叠圆形进度条
GraphicsPath 和矩阵类
连接不同的形状
绘制透明/半透明自定义控件

// Assign the Color used to draw the border of a shape to this Field
Color SelectedColor = Color.LightGreen;
List<DrawingRectangle> drawingRects = new List<DrawingRectangle>();

public class DrawingRectangle
{
    public Rectangle Rect => new Rectangle(Location, Size);
    public Size Size { get; set; }
    public Point Location { get; set; }
    public Control Owner { get; set; }
    public Point StartPosition { get; set; }
    public Color DrawingcColor { get; set; } = Color.LightGreen;
    public float PenSize { get; set; } = 3f;
}

private void form1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return; 
    DrawingRects.Add(new DrawingRectangle() {
        Location = e.Location,
        Size = Size.Empty,
        StartPosition = e.Location,
        Owner = (Control)sender,
        DrawingcColor = SelectedColor // <= Shape's Border Color
    });
}

private void form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;
    var dr = DrawingRects[DrawingRects.Count - 1];
    if (e.Y < dr.StartPosition.Y) { dr.Location = new Point(dr.Rect.Location.X, e.Y); }
    if (e.X < dr.StartPosition.X) { dr.Location = new Point(e.X, dr.Rect.Location.Y); }

    dr.Size = new Size(Math.Abs(dr.StartPosition.X - e.X), Math.Abs(dr.StartPosition.Y - e.Y));
    this.Invalidate();
}

private void form1_MouseUp(object sender, MouseEventArgs e)
{
    // The last drawn shape
    var dr = DrawingRects.Last();
    // ListBox used to present the shape coordinates
    lstPoints.Items.Add($"{dr.Location}, {dr.Size}");
}

private void form1_Paint(object sender, PaintEventArgs e)
{
    DrawShapes(e.Graphics);
}

private void DrawShapes(Graphics g)
{
    if (DrawingRects.Count == 0) return;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    foreach (var dr in DrawingRects) {
        using (Pen pen = new Pen(dr.DrawingcColor, dr.PenSize)) {
            g.DrawRectangle(pen, dr.Rect);
        };
    }
}

// A Button used to save the current drawing to a Bitmap
private void btnSave_Click(object sender, EventArgs e)
{
    using (var bitmap = new Bitmap(panCanvas.ClientRectangle.Width, panCanvas.ClientRectangle.Height))
    using (var g = Graphics.FromImage(bitmap)) {
        DrawShapes(g);
        bitmap.Save(@"[Image Path]", ImageFormat.Png);
        // Clone the Bitmap to show a thumbnail
    }
}

// A Button used to clear the current drawing
private void btnClear_Click(object sender, EventArgs e)
{
    drawingRects.Clear();
    this.Invalidate();
}
Run Code Online (Sandbox Code Playgroud)

绘制矩形