You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms中PictureBox鼠标绘点及矩形四角椭圆对齐问题

C# WinForms PictureBox 绘图问题解决方案

问题1:在鼠标点击位置绘制填充圆点

现有pictureBox2_MouseDown代码存在逻辑错误:手动将x和y设为0,导致后续坐标范围判断失效;且当前逻辑仅添加空尺寸的DrawingRectangle,未实现绘制圆点的需求。

修正后的MouseDown事件代码

private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;

    // 获取鼠标在PictureBox内的点击坐标
    Point mousePos = e.Location;

    if (pictureBox2.Image != null && selectedPath != null)
    {
        // 校验点击位置是否在Image范围内
        if (mousePos.X >= 0 && mousePos.X <= pictureBox2.Image.Size.Width && 
            mousePos.Y >= 0 && mousePos.Y <= pictureBox2.Image.Size.Height)
        {
            int pointSize = 15;
            // 添加用于绘制圆点的DrawingRectangle,让圆点中心对齐鼠标位置
            DrawingRects.Add(new DrawingRectangle()
            {
                Location = new Point(mousePos.X - pointSize/2, mousePos.Y - pointSize/2),
                Size = new Size(pointSize, pointSize),
                DrawingcColor = SelectedColor,
                Owner = (Control)sender
            });
            // 触发重绘更新界面
            pictureBox2.Invalidate();
        }
    }
}

Paint事件与绘制逻辑调整

修改pictureBox2_Paint事件,移除不必要的DrawingRects.Count > 0判断,确保有内容时就触发绘制:

private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    if (pictureBox2.Image != null && selectedPath != null)
    {
        DrawShapes(e.Graphics);
    }
}

更新DrawShapes方法,增加圆点绘制逻辑:

private void DrawShapes(Graphics g)
{
    if (DrawingRects.Count == 0) return;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    
    foreach (var dr in DrawingRects)
    {
        // 绘制圆点(尺寸为15x15的填充椭圆)
        if (dr.Size.Width == 15 && dr.Size.Height == 15)
        {
            using (SolidBrush brush = new SolidBrush(dr.DrawingcColor))
            {
                g.FillEllipse(brush, dr.Rect);
            }
        }
        // 绘制矩形及四角控制点(逻辑见问题2)
        else if (dr.Rect.Width > 0 && dr.Rect.Height > 0)
        {
            using (Pen pen = new Pen(dr.DrawingcColor, DrawingRectangle.PenSize))
            {
                g.DrawRectangle(pen, dr.Rect);
                int handleSize = 15;
                g.FillEllipse(Brushes.Red, dr.Rect.Left - handleSize/2, dr.Rect.Top - handleSize/2, handleSize, handleSize);
                g.FillEllipse(Brushes.Red, dr.Rect.Left - handleSize/2, dr.Rect.Bottom - handleSize/2, handleSize, handleSize);
                g.FillEllipse(Brushes.Red, dr.Rect.Right - handleSize/2, dr.Rect.Top - handleSize/2, handleSize, handleSize);
                g.FillEllipse(Brushes.Red, dr.Rect.Right - handleSize/2, dr.Rect.Bottom - handleSize/2, handleSize, handleSize);
            }
        }
    }
}

可选:抽离AddPoint方法

如果需要复用添加点的逻辑,可封装为单独方法:

private void AddPoint(Point mousePos, Color color)
{
    if (pictureBox2.Image == null || selectedPath == null) return;
    
    if (mousePos.X >= 0 && mousePos.X <= pictureBox2.Image.Size.Width && 
        mousePos.Y >= 0 && mousePos.Y <= pictureBox2.Image.Size.Height)
    {
        int pointSize = 15;
        DrawingRects.Add(new DrawingRectangle()
        {
            Location = new Point(mousePos.X - pointSize/2, mousePos.Y - pointSize/2),
            Size = new Size(pointSize, pointSize),
            DrawingcColor = color,
            Owner = pictureBox2
        });
        pictureBox2.Invalidate();
    }
}

在MouseDown事件中调用:AddPoint(e.Location, SelectedColor);


问题2:修正矩形四角填充椭圆的位置

现有代码中,Rect.Bottom和Rect.Right是矩形的外边缘坐标,直接作为椭圆左上角坐标会导致椭圆超出矩形范围。需将椭圆位置向左、向上偏移椭圆尺寸的一半,让椭圆中心对齐矩形边角,确保椭圆完全在矩形内部或贴合边角。

修正后的DrawShapes方法(四角控制点部分)

private void DrawShapes(Graphics g)
{
    if (DrawingRects.Count == 0) return;
    g.SmoothingMode = SmoothingMode.AntiAlias;
    foreach (var dr in DrawingRects)
    {
        if (dr.Rect.Width > 0 && dr.Rect.Height > 0)
        {
            using (Pen pen = new Pen(dr.DrawingcColor, DrawingRectangle.PenSize))
            {
                g.DrawRectangle(pen, dr.Rect);
                int handleSize = 15;
                // 左上角:中心对齐矩形左上角
                g.FillEllipse(Brushes.Red, dr.Rect.Left - handleSize/2, dr.Rect.Top - handleSize/2, handleSize, handleSize);
                // 左下角:中心对齐矩形左下角
                g.FillEllipse(Brushes.Red, dr.Rect.Left - handleSize/2, dr.Rect.Bottom - handleSize/2, handleSize, handleSize);
                // 右上角:中心对齐矩形右上角
                g.FillEllipse(Brushes.Red, dr.Rect.Right - handleSize/2, dr.Rect.Top - handleSize/2, handleSize, handleSize);
                // 右下角:中心对齐矩形右下角
                g.FillEllipse(Brushes.Red, dr.Rect.Right - handleSize/2, dr.Rect.Bottom - handleSize/2, handleSize, handleSize);
            };
        }
    }
}

逻辑说明

  • 椭圆尺寸为15x15,偏移量取15/2=7(整数运算)
  • 通过偏移让椭圆中心与矩形边角重合,既保证控制点贴合边角,又不会超出矩形范围

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:18:12