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

在WinForm中实现两个矩形的独立垂直拖拽功能

解决两个矩形独立拖拽的问题

你的代码核心问题是没有记录当前选中的是哪个矩形,所以鼠标拖动时只会固定修改topMarker的位置,不管你点的是哪个矩形。要实现选中哪个拖哪个,只需要加个变量跟踪选中的目标,再调整事件逻辑即可。

修改后的完整代码

using System.Drawing;

public partial class Form1 : Form
{
    Rectangle topMarker = new Rectangle(50, 125, 50, 2);
    Rectangle bottomMarker = new Rectangle(50, 200, 50, 2);
   
    // 新增:记录当前选中的矩形,未选中时为null
    Rectangle? selectedRect = null;
    
    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.FillRectangle(new SolidBrush(Color.Green), topMarker);
        e.Graphics.FillRectangle(new SolidBrush(Color.Red), bottomMarker);
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        // 检查鼠标点击位置是否在topMarker内
        if (topMarker.Contains(e.Location))
        {
            selectedRect = topMarker;
        }
        // 检查是否在bottomMarker内
        else if (bottomMarker.Contains(e.Location))
        {
            selectedRect = bottomMarker;
        }
        // 没点中任何矩形,不设置选中状态
        else
        {
            selectedRect = null;
        }
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        // 只有选中了矩形,才执行拖动逻辑
        if (selectedRect != null)
        {
            // 保持X坐标固定为50,只修改Y坐标
            var rect = selectedRect.Value;
            rect.X = 50;
            rect.Y = e.Y - rect.Height / 2; // 让鼠标在矩形中心拖动,体验更好(可选)

            // 边界限制:不能超出PictureBox顶部
            if (rect.Y < 0)
            {
                rect.Y = 0;
            }
            // 边界限制:不能超出PictureBox底部
            if (rect.Y + rect.Height > pictureBox1.Height)
            {
                rect.Y = pictureBox1.Height - rect.Height;
            }

            // 更新选中的矩形(因为Rectangle是值类型,需要重新赋值)
            if (selectedRect == topMarker)
            {
                topMarker = rect;
            }
            else
            {
                bottomMarker = rect;
            }

            Refresh();
        }
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        // 松开鼠标,取消选中状态
        selectedRect = null;
    }
}

关键改动说明

  1. 新增selectedRect变量:用可空的Rectangle?类型,专门记录当前被点击选中的矩形,未选中时为null。
  2. MouseDown事件逻辑调整:点击时判断鼠标位置落在哪个矩形内,给selectedRect赋值对应的矩形,没点中就设为null。
  3. MouseMove事件逻辑调整:只在selectedRect不为null时执行拖动,并且只修改这个选中矩形的位置,同时保持X坐标固定为50。
  4. 优化拖动体验:加入了rect.Y = e.Y - rect.Height / 2,让鼠标点击矩形的任意位置时,矩形都会跟着鼠标中心移动(如果不需要可以去掉这行,直接用rect.Y = e.Y)。
  5. 完善边界判断:原代码的底部边界判断有问题,改成rect.Y + rect.Height > pictureBox1.Height,确保矩形不会完全超出PictureBox底部。

这样修改后,点击绿色矩形就只会拖动它,点击红色矩形只会拖动红色的,两个矩形的操作完全独立,互不影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:53:08