如何在鼠标悬停时获得水平和垂直线?

时间:2011-06-17 07:39:31

标签: c# .net mouseevent draw pixel

NET编程。我有一张地图上有纬度和经度的地图。现在我在地图上拖动鼠标时,我应该得到一个矩形,鼠标点有一个顶点,左上角有一个顶点对于地图,我可以准确地针对纬度和经度定位像素。要清楚当我们在屏幕上拖动鼠标时它应该显示为矩形。我有一个部分工作的代码

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        // "e.X" and "e.Y" are used to get MousePositionX and MousePositionY
        rect = new Rectangle(e.X, e.Y, 0, 0);
        this.Invalidate();
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        // This makes sure that the left mouse button is pressed.
        if (e.Button == MouseButtons.Left)
        {
            // Draws the rectangle as the mouse moves
            rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
        }
        this.Invalidate();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {

        using (Pen pen = new Pen(Color.Red, 2))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }

我不知道问题的确切位置,但可以在运行时绘制一个矩形。任何一个请帮我修改代码。

3 个答案:

答案 0 :(得分:1)

需要进行两项简单的更改;

而不是this.Invalidate()来电pictureBox1.Invalidate()

在mouseMove方法中生成矩形为;

rect = new Rectangle(0, 0, e.X, e.Y);

由于您希望左上角(0,0)成为矩形的另一角。

答案 1 :(得分:1)

我建议创建自己的画布控件( [编辑:继承自PictureBox] ),并启用双缓冲。这将减少绘图时的闪烁。

public partial class DrawingCanvas : PictureBox
{
    public DrawingCanvas()
    {
        InitializeComponent();
        SetStyle(
              ControlStyles.AllPaintingInWmPaint | 
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.ResizeRedraw, true);
    }

    private Point start = new Point(0, 0);
    private Point end = new Point(0, 0);

    protected override void OnMouseDown(MouseEventArgs e)
    {
        start = e.Location;
        end = e.Location;
        Invalidate();
        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // This makes sure that the left mouse button is pressed.
        if (e.Button == MouseButtons.Left)
            end = e.Location;

        Invalidate();
        base.OnMouseMove(e);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        int top = start.Y < end.Y ? start.Y : end.Y;
        int left = start.X < end.X ? start.X : end.X;
        int width = end.X - start.X; if (width < 0) width = -width;
        int height = end.Y - start.Y; if (height < 0) height = -height;
        Rectangle rect = new Rectangle(left, top, width, height);

        using (Pen pen = new Pen(Color.Red, 2))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }
}

请注意,DrawRectangle不接受负宽度或高度,因此您必须在OnPaint方法中处理此问题。

将此控件添加到项目后,编译项目。您的自定义控件应该可以在Visual Studio的“工具箱”窗口中找到。如果不是,您可以右键单击工具箱并选择Choose Items...将画布添加到工具箱,或只是将Panel控件添加到Form,打开{{ 1}}文件,并用Form.Designer.cs(或您选择的任何名称)替换所有Panel引用。

设置背景图片时,请使用DrawingCanvas属性。

答案 2 :(得分:1)

tafa的答案有效。

我只有两个补充:

  1. 你应该在MouseDown方法中 也使用以下代码。所以 一旦你点击地图中的某个地方 即使不是,你也会得到一个矩形 移动鼠标。

    rect = new Rectangle(0, 0, e.X, e.Y);
    
  2. 在MouseMove方法中,我将使用以下代码,每当您移动鼠标时都不会创建新的矩形:

    rect.Width = e.X;  
    rect.Height = e.Y;