[英]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;
凡initiallySelectedX
和initiallySelectedY
是變量設置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();
}
把事情簡單化。
相關文章
更新:
跟蹤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.