[C#]ユーザーコントロールをドラッグアンドドロップで移動で面白そうなことやってるので書いてみました。結構泥臭くなりますね。ちょっと嵌ってしまって時間が掛かったのはここだけの秘密。
using System.Drawing;
using System.Windows.Forms;
public partial class UserControl1 :UserControl {
Size lastMouseDownSize;
Point lastMouseDownPoint;
DAndDStatus status;
int sizeChangeArea = 8;
public UserControl1() {
InitializeComponent();
}
protected override void OnMouseDown(MouseEventArgs e) {
lastMouseDownPoint = e.Location;
lastMouseDownSize = this.Size;
//動作を決定
status = DAndDStatus.None;
if(getTop().Contains(e.Location)) {
status |= DAndDStatus.Top;
}
if(getLeft().Contains(e.Location)) {
status |= DAndDStatus.Left;
}
if(getBottom().Contains(e.Location)) {
status |= DAndDStatus.Bottom;
}
if(getRight().Contains(e.Location)) {
status |= DAndDStatus.Right;
}
if(status == DAndDStatus.None) {
status = DAndDStatus.Move;
} else {
this.Capture = true;
}
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e) {
//カーソルを変更
if((getTop().Contains(e.Location) &&
getLeft().Contains(e.Location)) ||
(getBottom().Contains(e.Location) &&
getRight().Contains(e.Location))) {
this.Cursor = Cursors.SizeNWSE;
} else if((getTop().Contains(e.Location) &&
getRight().Contains(e.Location)) ||
(getBottom().Contains(e.Location) &&
getLeft().Contains(e.Location))) {
this.Cursor = Cursors.SizeNESW;
} else if(getTop().Contains(e.Location) ||
getBottom().Contains(e.Location)) {
this.Cursor = Cursors.SizeNS;
} else if(getLeft().Contains(e.Location) ||
getRight().Contains(e.Location)) {
this.Cursor = Cursors.SizeWE;
} else {
this.Cursor = Cursors.Default;
}
if(e.Button == MouseButtons.Left) {
int diffX = e.X - lastMouseDownPoint.X;
int diffY = e.Y - lastMouseDownPoint.Y;
if((status & DAndDStatus.Move) == DAndDStatus.Move) {
this.Left += diffX;
this.Top += diffY;
}
if((status & DAndDStatus.Top) == DAndDStatus.Top) {
int h = this.Height;
this.Height -= diffY;
this.Top += h - this.Height;
}
if((status & DAndDStatus.Bottom) == DAndDStatus.Bottom) {
this.Height = lastMouseDownSize.Height + diffY;
}
if((status & DAndDStatus.Left) == DAndDStatus.Left) {
int w = this.Width;
this.Width -= diffX;
this.Left += w - this.Width;
}
if((status & DAndDStatus.Right) == DAndDStatus.Right) {
this.Width = lastMouseDownSize.Width + diffX;
}
}
this.Refresh();
base.OnMouseMove(e);
}
protected override void OnMouseUp(MouseEventArgs e) {
this.Capture = false;
base.OnMouseUp(e);
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.DrawRectangle(
Pens.Black,
0, 0,
this.Width - 1,
this.Height - 1);
base.OnPaint(e);
}
private Rectangle getTop() {
return new Rectangle(0, 0, this.Width, sizeChangeArea);
}
private Rectangle getBottom() {
return new Rectangle(0, this.Height - sizeChangeArea,
this.Width, sizeChangeArea);
}
private Rectangle getLeft() {
return new Rectangle(0,0,
sizeChangeArea, this.Height);
}
private Rectangle getRight() {
return new Rectangle(this.Width - sizeChangeArea, 0,
sizeChangeArea, this.Height);
}
private enum DAndDStatus {
None = 0,
Move = 1,
Top = 2,
Bottom = 4,
Left = 8,
Right = 16,
}
}