オブジェクトをマウスで動かす

GUI のプログラムを作る時にどうしてもやってみたいことがある。それは、ドローツールの場合のようにオブジェクトをマウスでドラッグして動かすことだ。基本的なテクニックだが、参考書にもあまりないし、ネットで検索してもなかった。いちおう次のようにすると動いたが、他のプログラムを参考にしたわけではないので、これでいいのかどうかは分からない。

プログラムの作成はまずプロジェクトを作成したら、フォームの上にボタンを一つだけ貼り付ける。

つぎに、ボタンの上で、MouseDown イベント、MouseMove イベント、MouseUp イベントを捕捉して動作させるようにした。

下のプログラムは、Form1.cs に書き込むが、下のソースを動かすためには、イベントハンドラーをボタンオブジェクトに追加しておかなくてはならない。

イベントハンドラーの追加は、Form1.Designer.cs のInitializeComponent() メソッドの中で行うが、Form1.Designer.cs を直接編集するよりは、フォームデザイナーでやった方がいい。フォームデザイナーでボタンを選択しておいてプロパティウィンドウの稲妻印のイベントアイコンをクリックすると、使えるイベントのリストが表示される。そこで、MouseDown などのイベント名のラベルをダブルクリックするとコールバックルーチンを記述することができる。このとき同時にForm1.Designer.cs にはMouseDown のイベントハンドラーを追加する記述が挿入されている。

また、マウスのドラッグ操作関連で使うので、Form1オブジェクトに、pointOffset と isActive のふたつのインスタンス変数を追加しておく。

public partial class Form1 : Form
{
  private bool isActive = false;
  private Point pointOffset;

  public Form1()
  {
    InitializeComponent();
  }

  private void button1_MouseDown(object sender, MouseEventArgs e)
  {
    pointOffset = new Point(this.PointToClient(Cursor.Position).X - button1.(Location).X,
this.PointToClient(Cursor.Position).Y - button1.(Location).Y);
    isActive = true;
  }

  private void Form1_MouseMove(object sender, MouseEventArgs e)
  {
    if (isActive == true)
    {
         button1.(Location) = new Point(this.PointToClient(Cursor.Position).X - pointOffset.X,
         this.PointToClient(Cursor.Position).Y - pointOffset.Y);
    }
  }

  private void button1_MouseUp(object sender, MouseEventArgs e)
  {
    isActive = false;
  }
}

* ブログの制限の関係で(Location)にしていますが、()をとって使ってください。

MouseDown イベントで、カーソルの位置とボタンのLocationの差を計算し、isActive フラグをtrue にする。MouseMove イベントで isActive フラグが true ならマウスカーソルの位置からボタンのLocationを計算しLocationの値を設定しなおす。MouseUp イベントで isActive フラグを false にする。

たったこれだけの操作で、ボタンをマウスで自由にドラッグして動かすことができるようになった。

どこからか引用したものではないのでバグがあるかもしれないが、自分でつかうプログラムなら問題ないし、他のソースを読むときも理解しやすいのではないだろうか。
[PR]
by tnomura9 | 2010-01-25 17:12 | C# | Comments(0)
<< コールバック フリック入力に慣れた >>