簡體   English   中英

如何在使用 C# MouseDown 后在任何方向繪制矩形?

[英]How to draw a Rectangle in any direction after MouseDown using C#?

如何在所有方向上繪制矩形? 當前代碼:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    // Starting point of the selection:
    if (e.Button == MouseButtons.Left)
    {
        _selecting = true;
        _selection = new Rectangle(new Point(e.X, e.Y), new Size());
    }
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    // Update the actual size of the selection:
    if (_selecting)
    {
        _selection.Width = e.X - _selection.X;
        _selection.Height = e.Y - _selection.Y;
        pictureBox1.Refresh(); // redraw picturebox

    }
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && _selecting)
    {
        _selecting = false;
    }
}

這允許我使用MouseDown然后向下和向右繪制,但我無法在錨點之外的任何其他方向繪制。 如何在任何方向上繪制矩形,例如 Microsoft Paint?

在此處輸入圖片說明

我第一次嘗試:

_selection.Width = Math.Abs(e.X - _selection.X);
_selection.Height = Math.Abs(e.Y - _selection.Y);

但這會產生一個有趣的鏡像效果(這不是我想要的)。 然后我嘗試了一個簡單的轉變:

_selection.X = _selection.Left - 5;

這符合我的預期並將靜態矩形向左移動 5 個單位,所以我認為在 Paint 事件期間連續移動錨點是一個簡單的問題:

private void UpdateRectange(Point newPos)
{
    var width = newPos.X - _selection.X;
    var height = newPos.Y - _selection.Y;
    _selection.Width = Math.Abs(width);
    _selection.Height = Math.Abs(height);
    if (width < 0 && height > 0) // move down (+) and left (-)
    {
        //_selection.X = _selection.Left + width;
        _selection.Offset(width, 0);
    }
    uxScreenGrab.Refresh(); // redraw picturebox
}

但這導致當移動到原始錨點的左側時,屏幕上的一條垂直線向左推。由於某種原因,寬度沒有正確更新。

在此處輸入圖片說明

問題中提出的解決方案看起來不錯:

_selection.Width = Math.Abs(e.X - initiallySelectedX);
_selection.Height = Math.Abs(e.Y - initiallySelectedY);

...但是當 (eX - initialSelectedX) < 0 時,您必須移動矩形的原點

所以可能你想在你的代碼中添加這樣的東西:

var diffX = e.x - initiallySelectedX;
if (diffX < 0) _selection.X = initiallySelectedX - diffX;
var diffY = e.y - initiallySelectedY;
if (diffY < 0) _selection.Y = initiallySelectedY - diffY;

initiallySelectedXinitiallySelectedY是變量設置onMouseDown 這只是一個粗略的想法。 背后的想法是矩形的寬度和高度不能為負!!

這是在PictureBox上繪制選擇矩形的另一個片段:

//...
private Point startPoint;
private Point endPoint;
private readonly Pen P1 = new Pen(Color.SteelBlue, 2) {
    Alignment = PenAlignment.Center, DashStyle = DashStyle.Dash};
//...

MouseDown事件中設置startPoint並重置endPoint變量:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        startPoint = new Point(e.X, e.Y);
        endPoint = Point.Empty;
    }
}

設置endPoint並在MouseMove事件中調用Invalidate()方法:

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    var p = new Point(e.X, e.Y);

    if (e.Button == MouseButtons.Left &&
        !p.Equals(startPoint))
    {
        endPoint = p;
        pictureBox1.Invalidate();
    }
}

同樣在MouseUp事件中調用Invalidate()來移除選擇矩形:

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    pictureBox1.Invalidate();
}

繪制選擇矩形:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if(MouseButtons == MouseButtons.Left &&
        !startPoint.Equals(endPoint) &&
        !endPoint.Equals(Point.Empty))
    {
        var g = e.Graphics;
        var rect = Rectangle.Empty;

        if(startPoint.X < endPoint.X)
        {
            rect.X = startPoint.X;
            rect.Width = endPoint.X - startPoint.X;
        }
        else
        {
            rect.X = endPoint.X;
            rect.Width = startPoint.X - endPoint.X;
        }
        if(startPoint.Y < endPoint.Y)
        {
            rect.Y = startPoint.Y;
            rect.Height = endPoint.Y - startPoint.Y;
        }
        else
        {
            rect.Y = endPoint.Y;
            rect.Height = startPoint.Y - endPoint.Y;
        }
        g.DrawRectangle(P1, rect);
    }
}

並且不要忘記清理:

private void YourForm_FormClosing(object sender, FormClosingEventArgs e)
{
    P1.Dispose();
}

把事情簡單化。

SOQ60022534

相關文章

如何調用使用 PaintEventArgs 和坐標變量的方法

更新:

跟蹤MouseDown事件的起點可以讓錨點正確更新:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    // Starting point of the selection:
    if (e.Button == MouseButtons.Left)
    {
        _selecting = true;
        _selection = new Rectangle(new Point(e.X, e.Y), new Size());
        _startingPoint = e.Location;
    }
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    // Update the actual size of the selection:
    if (_selecting)
    {
        UpdateRectange(e.Location);
    }
}

private void UpdateRectange(Point newPos)
{
    var diffX = newPos.X - _startingPoint.X;
    var diffY = newPos.Y - _startingPoint.Y;
    var newSize = new Size(Math.Abs(diffX), Math.Abs(diffY));
    if (diffX > 0 && diffY > 0)
    {
        _selection = new Rectangle(_startingPoint, newSize);
    }
    else if (diffX < 0 && diffY < 0)
    {
        _selection = new Rectangle(newPos, newSize);
    }
    else if (diffX > 0 && diffY < 0)
    {
        _selection = new Rectangle(new Point(_startingPoint.X, _startingPoint.Y + diffY), newSize);
    }
    else
    {
        _selection = new Rectangle(new Point(_startingPoint.X + diffX, _startingPoint.Y), newSize);
    }
    uxScreenGrab.Invalidate();
}

更新 2:

重新編寫UpdateRectangle以簡單地移動錨點,而不是在每次調用時實例化:

private void UpdateRectange(Point newPos)
{
    var diffX = newPos.X - _startingPoint.X;
    var diffY = newPos.Y - _startingPoint.Y;
    var newSize = new Size(Math.Abs(diffX), Math.Abs(diffY));
    if (diffX > 0 && diffY > 0)
    {
        _selection.Size = newSize;
    }
    else if (diffX < 0 && diffY < 0)
    {
        _selection.Location = newPos;
        _selection.Size = newSize;
    }
    else if (diffX > 0 && diffY < 0)
    {
        _selection.Y = _startingPoint.Y + diffY;
        _selection.Size = newSize;
    }
    else
    {
        _selection.X = _startingPoint.X + diffX;
        _selection.Size = newSize;
    }
    uxScreenGrab.Invalidate();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM