Resize and reposition control based on 2 child 矩形(椭圆)图形位置
Resize and reposition control based on 2 child Rectangle (ellipse) graphics position
正如标题所说,如果我将 2 个椭圆手柄拖到我制作的自定义控件中,我只需要正确地调整大小和重新定位控件。我似乎不知道该怎么做。
在上面的 GIF 中,我的控件是黄色背景,当我开始将第二个手柄移到第四象限之外时出现问题。它需要正确地重新定位和调整控件的大小。
代码:
public partial class FlexibleLineControl : Control
{
public FlexibleLineControl()
{
// transparent control: https://www.c-sharpcorner.com/uploadfile/Nildo/making-transparent-control-using-gdi-and-C-Sharp-updated-to-net-3-5/
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.PaleGoldenrod;
InitializeComponent();
this.Size = new Size(HandleSize.Width * 2, HandleSize.Height * 2);
Handle1 = new Rectangle(new Point(0, 0), HandleSize);
Handle2 = new Rectangle(new Point(HandleSize.Width, HandleSize.Height), HandleSize);
GP1.AddEllipse(Handle1);
GP2.AddEllipse(Handle2);
DoubleBuffered = true;
}
private GraphicsPath GP1 = new GraphicsPath();
private GraphicsPath GP2 = new GraphicsPath();
private Size HandleSize = new Size(10, 10);
public Rectangle Handle1;
private Rectangle Handle2;
private Point CurrMousePoint1;
private bool DragState = false;
private bool Handle1Dragged = false;
private bool Handle2Dragged = false;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillEllipse(Brushes.Black, Handle1);
e.Graphics.FillEllipse(Brushes.Black, Handle2);
// get line points to draw line
Point p1 = new Point(Handle1.Location.X + Handle1.Width / 2, Handle1.Location.Y + Handle1.Height / 2);
Point p2 = new Point(Handle2.Location.X + Handle2.Width / 2, Handle2.Location.Y + Handle2.Height / 2);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawLine(new Pen(Brushes.Black), p1, p2);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (GP1.IsVisible(e.Location))
{
DragState = true;
Handle1Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
else if (GP2.IsVisible(e.Location))
{
DragState = true;
Handle2Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (DragState)
{
Point newPoint = Parent.PointToClient(Cursor.Position);
if (Handle1Dragged)
Handle1.Location = new Point(Handle1.X + newPoint.X - CurrMousePoint1.X, Handle1.Y + newPoint.Y - CurrMousePoint1.Y);
else if (Handle2Dragged)
Handle2.Location = new Point(Handle2.X + newPoint.X - CurrMousePoint1.X, Handle2.Y + newPoint.Y - CurrMousePoint1.Y);
// get new control size and location
int width = Math.Abs(Handle1.Location.X - Handle2.Location.X);
int height = Math.Abs(Handle1.Location.Y - Handle2.Location.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
CurrMousePoint1 = newPoint;
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
DragState = false;
if (Handle1Dragged)
{
GP1.Reset();
GP1.AddRectangle(Handle1);
Handle1Dragged = false;
}
else if (Handle2Dragged)
{
GP2.Reset();
GP2.AddRectangle(Handle2);
Handle2Dragged = false;
}
}
}
感谢评论,现在可以使用了
工作代码:
class FlexibleLineControl : Control
{
public FlexibleLineControl()
{
this.Size = new Size(HandleSize.Width * 2, HandleSize.Height * 2);
this.Location = new Point(0, 0);
InitControl();
}
public FlexibleLineControl(Point p1, Point p2)
{
this.Location = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
int width = Math.Abs(p1.X - p2.X);
int height = Math.Abs(p1.Y - p2.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
InitControl();
}
public Size HandleSize { get; set; } = new Size(10, 10);
public Color HandleColor { get; set; } = Color.Black;
public float LineWidth { get; set; } = 1;
public Color LineColor { get; set; } = Color.Black;
public Point LinePoint1 { get; set; }
public Point LinePoint2 { get; set; }
private GraphicsPath GP1 = new GraphicsPath();
private GraphicsPath GP2 = new GraphicsPath();
public Rectangle Handle1;
private Rectangle Handle2;
private Point CurrMousePoint1;
private bool DragState = false;
private bool Handle1Dragged = false;
private bool Handle2Dragged = false;
private void InitControl()
{
// transparent control: https://www.c-sharpcorner.com/uploadfile/Nildo/making-transparent-control-using-gdi-and-C-Sharp-updated-to-net-3-5/
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.ResizeRedraw, true);
//Set style for double buffering
SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
this.DoubleBuffered = true;
Handle1 = new Rectangle(new Point(0, 0), HandleSize);
Handle2 = new Rectangle(new Point(this.Size.Width - HandleSize.Width, this.Size.Height - HandleSize.Height), HandleSize);
LinePoint1 = new Point(Handle1.X + Handle1.Width / 2, Handle1.Y + Handle1.Height / 2);
LinePoint2 = new Point(Handle2.X + Handle2.Width / 2, Handle2.Y + Handle2.Height / 2);
GP1.AddEllipse(Handle1);
GP2.AddEllipse(Handle2);
}
#region Move and Draw event overrides
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillEllipse(new SolidBrush(HandleColor), Handle1);
e.Graphics.FillEllipse(new SolidBrush(HandleColor), Handle2);
// get line points to draw line
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawLine(new Pen(Brushes.Black, LineWidth), LinePoint1, LinePoint2);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (GP1.IsVisible(PointToClient(Cursor.Position)))
{
DragState = true;
Handle1Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
else if (GP2.IsVisible(e.Location))
{
DragState = true;
Handle2Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (DragState)
{
Point newPoint = Parent.PointToClient(Cursor.Position);
if (Handle1Dragged)
Handle1.Location = new Point(Handle1.X + newPoint.X - CurrMousePoint1.X, Handle1.Y + newPoint.Y - CurrMousePoint1.Y);
else if (Handle2Dragged)
Handle2.Location = new Point(Handle2.X + newPoint.X - CurrMousePoint1.X, Handle2.Y + newPoint.Y - CurrMousePoint1.Y);
// get new control size
int width = Math.Abs(Handle1.X - Handle2.X);
int height = Math.Abs(Handle1.Y - Handle2.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
// get new control location
Point p1 = Handle1.Location;
Point p2 = Handle2.Location;
if (!(p1.X == p2.X || p1.Y == p2.Y))
{
this.Location = new Point(Location.X + Math.Min(Handle1.X, Handle2.X), Location.Y + Math.Min(Handle1.Y, Handle2.Y));
// p1 top right, p2 bottom left
if (p1.X > p2.X && p1.Y < p2.Y)
{
p1 = new Point(this.Size.Width - this.HandleSize.Width, 0);
p2 = new Point(0, this.Size.Height - this.HandleSize.Height);
}
// p1 bottom right, p2 top left
else if (p1.X > p2.X && p1.Y > p2.Y)
{
p1 = new Point(this.Size.Width - this.HandleSize.Width, this.Size.Height - this.HandleSize.Height);
p2 = new Point();
}
// p1 top left, p2 bottom right
else if (p1.X < p2.X && p1.Y < p2.Y)
{
p1 = new Point();
p2 = new Point(this.Size.Width - this.HandleSize.Width, this.Size.Height - this.HandleSize.Height);
}
// p1 bottom left, p2 top right
else if (p1.X < p2.X && p1.Y > p2.Y)
{
p1 = new Point(0, this.Size.Height - this.HandleSize.Height);
p2 = new Point(this.Size.Width - this.HandleSize.Width, 0);
}
}
Handle1.Location = p1;
Handle2.Location = p2;
LinePoint1 = new Point(Handle1.X + Handle1.Width / 2, Handle1.Y + Handle1.Height / 2);
LinePoint2 = new Point(Handle2.X + Handle2.Width / 2, Handle2.Y + Handle2.Height / 2);
CurrMousePoint1 = newPoint;
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
DragState = false;
Handle1Dragged = false;
Handle2Dragged = false;
GP1.Reset();
GP1.AddRectangle(Handle1);
GP2.Reset();
GP2.AddRectangle(Handle2);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
#endregion
}
正如标题所说,如果我将 2 个椭圆手柄拖到我制作的自定义控件中,我只需要正确地调整大小和重新定位控件。我似乎不知道该怎么做。
在上面的 GIF 中,我的控件是黄色背景,当我开始将第二个手柄移到第四象限之外时出现问题。它需要正确地重新定位和调整控件的大小。
代码:
public partial class FlexibleLineControl : Control
{
public FlexibleLineControl()
{
// transparent control: https://www.c-sharpcorner.com/uploadfile/Nildo/making-transparent-control-using-gdi-and-C-Sharp-updated-to-net-3-5/
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.PaleGoldenrod;
InitializeComponent();
this.Size = new Size(HandleSize.Width * 2, HandleSize.Height * 2);
Handle1 = new Rectangle(new Point(0, 0), HandleSize);
Handle2 = new Rectangle(new Point(HandleSize.Width, HandleSize.Height), HandleSize);
GP1.AddEllipse(Handle1);
GP2.AddEllipse(Handle2);
DoubleBuffered = true;
}
private GraphicsPath GP1 = new GraphicsPath();
private GraphicsPath GP2 = new GraphicsPath();
private Size HandleSize = new Size(10, 10);
public Rectangle Handle1;
private Rectangle Handle2;
private Point CurrMousePoint1;
private bool DragState = false;
private bool Handle1Dragged = false;
private bool Handle2Dragged = false;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillEllipse(Brushes.Black, Handle1);
e.Graphics.FillEllipse(Brushes.Black, Handle2);
// get line points to draw line
Point p1 = new Point(Handle1.Location.X + Handle1.Width / 2, Handle1.Location.Y + Handle1.Height / 2);
Point p2 = new Point(Handle2.Location.X + Handle2.Width / 2, Handle2.Location.Y + Handle2.Height / 2);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawLine(new Pen(Brushes.Black), p1, p2);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (GP1.IsVisible(e.Location))
{
DragState = true;
Handle1Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
else if (GP2.IsVisible(e.Location))
{
DragState = true;
Handle2Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (DragState)
{
Point newPoint = Parent.PointToClient(Cursor.Position);
if (Handle1Dragged)
Handle1.Location = new Point(Handle1.X + newPoint.X - CurrMousePoint1.X, Handle1.Y + newPoint.Y - CurrMousePoint1.Y);
else if (Handle2Dragged)
Handle2.Location = new Point(Handle2.X + newPoint.X - CurrMousePoint1.X, Handle2.Y + newPoint.Y - CurrMousePoint1.Y);
// get new control size and location
int width = Math.Abs(Handle1.Location.X - Handle2.Location.X);
int height = Math.Abs(Handle1.Location.Y - Handle2.Location.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
CurrMousePoint1 = newPoint;
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
DragState = false;
if (Handle1Dragged)
{
GP1.Reset();
GP1.AddRectangle(Handle1);
Handle1Dragged = false;
}
else if (Handle2Dragged)
{
GP2.Reset();
GP2.AddRectangle(Handle2);
Handle2Dragged = false;
}
}
}
感谢评论,现在可以使用了
工作代码:
class FlexibleLineControl : Control
{
public FlexibleLineControl()
{
this.Size = new Size(HandleSize.Width * 2, HandleSize.Height * 2);
this.Location = new Point(0, 0);
InitControl();
}
public FlexibleLineControl(Point p1, Point p2)
{
this.Location = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
int width = Math.Abs(p1.X - p2.X);
int height = Math.Abs(p1.Y - p2.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
InitControl();
}
public Size HandleSize { get; set; } = new Size(10, 10);
public Color HandleColor { get; set; } = Color.Black;
public float LineWidth { get; set; } = 1;
public Color LineColor { get; set; } = Color.Black;
public Point LinePoint1 { get; set; }
public Point LinePoint2 { get; set; }
private GraphicsPath GP1 = new GraphicsPath();
private GraphicsPath GP2 = new GraphicsPath();
public Rectangle Handle1;
private Rectangle Handle2;
private Point CurrMousePoint1;
private bool DragState = false;
private bool Handle1Dragged = false;
private bool Handle2Dragged = false;
private void InitControl()
{
// transparent control: https://www.c-sharpcorner.com/uploadfile/Nildo/making-transparent-control-using-gdi-and-C-Sharp-updated-to-net-3-5/
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.ResizeRedraw, true);
//Set style for double buffering
SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
this.DoubleBuffered = true;
Handle1 = new Rectangle(new Point(0, 0), HandleSize);
Handle2 = new Rectangle(new Point(this.Size.Width - HandleSize.Width, this.Size.Height - HandleSize.Height), HandleSize);
LinePoint1 = new Point(Handle1.X + Handle1.Width / 2, Handle1.Y + Handle1.Height / 2);
LinePoint2 = new Point(Handle2.X + Handle2.Width / 2, Handle2.Y + Handle2.Height / 2);
GP1.AddEllipse(Handle1);
GP2.AddEllipse(Handle2);
}
#region Move and Draw event overrides
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillEllipse(new SolidBrush(HandleColor), Handle1);
e.Graphics.FillEllipse(new SolidBrush(HandleColor), Handle2);
// get line points to draw line
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawLine(new Pen(Brushes.Black, LineWidth), LinePoint1, LinePoint2);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (GP1.IsVisible(PointToClient(Cursor.Position)))
{
DragState = true;
Handle1Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
else if (GP2.IsVisible(e.Location))
{
DragState = true;
Handle2Dragged = true;
CurrMousePoint1 = this.Parent.PointToClient(Cursor.Position);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (DragState)
{
Point newPoint = Parent.PointToClient(Cursor.Position);
if (Handle1Dragged)
Handle1.Location = new Point(Handle1.X + newPoint.X - CurrMousePoint1.X, Handle1.Y + newPoint.Y - CurrMousePoint1.Y);
else if (Handle2Dragged)
Handle2.Location = new Point(Handle2.X + newPoint.X - CurrMousePoint1.X, Handle2.Y + newPoint.Y - CurrMousePoint1.Y);
// get new control size
int width = Math.Abs(Handle1.X - Handle2.X);
int height = Math.Abs(Handle1.Y - Handle2.Y);
this.Size = new Size(width + HandleSize.Width, height + HandleSize.Height);
// get new control location
Point p1 = Handle1.Location;
Point p2 = Handle2.Location;
if (!(p1.X == p2.X || p1.Y == p2.Y))
{
this.Location = new Point(Location.X + Math.Min(Handle1.X, Handle2.X), Location.Y + Math.Min(Handle1.Y, Handle2.Y));
// p1 top right, p2 bottom left
if (p1.X > p2.X && p1.Y < p2.Y)
{
p1 = new Point(this.Size.Width - this.HandleSize.Width, 0);
p2 = new Point(0, this.Size.Height - this.HandleSize.Height);
}
// p1 bottom right, p2 top left
else if (p1.X > p2.X && p1.Y > p2.Y)
{
p1 = new Point(this.Size.Width - this.HandleSize.Width, this.Size.Height - this.HandleSize.Height);
p2 = new Point();
}
// p1 top left, p2 bottom right
else if (p1.X < p2.X && p1.Y < p2.Y)
{
p1 = new Point();
p2 = new Point(this.Size.Width - this.HandleSize.Width, this.Size.Height - this.HandleSize.Height);
}
// p1 bottom left, p2 top right
else if (p1.X < p2.X && p1.Y > p2.Y)
{
p1 = new Point(0, this.Size.Height - this.HandleSize.Height);
p2 = new Point(this.Size.Width - this.HandleSize.Width, 0);
}
}
Handle1.Location = p1;
Handle2.Location = p2;
LinePoint1 = new Point(Handle1.X + Handle1.Width / 2, Handle1.Y + Handle1.Height / 2);
LinePoint2 = new Point(Handle2.X + Handle2.Width / 2, Handle2.Y + Handle2.Height / 2);
CurrMousePoint1 = newPoint;
Invalidate();
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
DragState = false;
Handle1Dragged = false;
Handle2Dragged = false;
GP1.Reset();
GP1.AddRectangle(Handle1);
GP2.Reset();
GP2.AddRectangle(Handle2);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
#endregion
}