C#|ユーザーコントロールをD&Dで移動&サイズ変更

[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,
    }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください