3 人のうち 1 人が役に立つと評価しました    - このトピックを評価する

ドラッグ アンド ドロップ操作の実行

Microsoft .NET へのアップグレード

Mike Gunderloy
Lark Group, Inc.

February 2002
日本語版最終更新日 2002 年 9 月 19 日

要約: Microsoft Visual Basic .NET でのドラッグ アンド ドロップの管理。

目標

  • Windows フォームにおけるドラッグ アンド ドロップを理解する。
  • Microsoft Visual Basic® .NET のコードを使って、ドラッグ アンド ドロップ操作を実行する。

前提条件

このドキュメントを有効に活用するためには、以下の条件が必要です。


  • Visual Basic プログラミングについての知識があること。
  • ドラッグ アンド ドロップの基本的な概念を理解していること。
  • Visual Basic .NET にアクセスできること。

目次

ドラッグ アンド ドロップ
ドラッグ アンド ドロップの実装の練習
要約

ドラッグ アンド ドロップ

ドラッグ アンド ドロップは Microsoft® Windows® オペレーティング システム ファミリの根本にあるメタファーの 1 つです。ユーザーは、一部のアイテムはマウスを押しながら動かすことができ、そのアイテムをドロップできる場所に来ると適切なビジュアル フィードバックが得られることを理解しています。ユーザーは、この方法によって、データやイメージを移動できることを期待しています。Visual Basic .NET では、独自のアプリケーションの中で簡単にドラッグ アンド ドロップを実装することができます。プログラマは、どのコントロールがドラッグ可能なのか、それによってどのようなデータがドラッグされるのか、そしてどこにドロップできるのかといったことを含めて、このプロセスのあらゆる側面を制御できます。これは 1 つのアプリケーションの中でも、異なるアプリケーションの間でも実装できます。このドキュメントでは、Visual Basic .NET でドラッグ アンド ドロップを管理する方法について説明します。

注   Visual Basic 6.0 の OLE のドラッグ アンド ドロップを扱ったことがある人は、Microsoft .NET のドラッグ アンド ドロップも理解しやすいでしょう。ただし、多くの用語と名前が変更されているので、以下の詳細に慎重に目を通すようにしてください。

ドラッグ アンド ドロップ操作の開始

ドラッグ アンド ドロップ操作を開始するには、Windows フォーム コントロールの DoDragDrop メソッドを呼び出します。DoDragDrop メソッドは System.Windows.Forms.Control クラスに実装されているので、Windows フォームの名前空間の中のすべてのコントロールで利用できます。

DoDragDrop メソッドは、ドラッグするデータと、このコントロールがサポートしているドラッグ操作の 2 つの引数を取ります。DoDragDrop メソッドはいつでも呼び出すことができますが、一般にはユーザーの期待に添って、MouseDown イベントをドラッグのトリガとして使用することになるでしょう。次に例を示します。



Private Sub txtDrag_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs)_
 Handles txtDrag.MouseDown

    txtDrag.DoDragDrop(txtDrag.Text, _
     DragDropEffects.Copy Or DragDropEffects.Move)

End Sub
                

この例のコードは、ユーザーが txt1 コントロール上で第 1 マウス ボタンを押したときにドラッグ操作を開始します。ドラッグされるデータはコントロールに含まれているテキストで、このコントロールはドラッグ アンド ドロップでコピーと移動の両方をサポートしています。

ヒント   ドラッグされるデータは、String、Bitmap、または MetaFile クラスのインスタンスであるか、ISerializable または IDataObject インターフェイスを実装しているオブジェクトでなくてはなりません。

DoDragDrop メソッドの第 2 の引数は、DragDropEffects 列挙体のメンバの組み合わせで、このデータに対してどのターゲット操作が有効であるかを指定します。表 1 はこの列挙体のメンバを示しています。

表 1. DragDropEffects 列挙体のメンバ


メンバ説明
Allデータはドラッグ ソースからコピーされ、削除されて、ターゲットにスクロールされます。
Copyデータはターゲットにコピーされます。
Linkデータはターゲットにリンクされます。
Moveデータはターゲットに移動されます。
Noneターゲットはデータを受け付けません。
Scrollターゲットでスクロールが開始されようとしているか、現在スクロールが行われています。

ドラッグ操作からのデータの受け取り

任意のコントロールが、進行中のドラッグ アンド ドロップ操作からデータを受け取ることができます。コントロールをドロップ ゾーンとして指定するには、次の 3 つの操作を行う必要があります。


  1. コントロールの AllowDrop プロパティを True に設定する。
  2. コントロールの DragEnter プロパティを処理する。
  3. コントロールの DragDrop プロパティを処理する。

DragEnter イベントは、ドラッグ アンド ドロップ操作が進行中で (つまり何らかのコントロールが DoDragDrop メソッドを呼び出しており)、カーソルがコントロールに入ったときに発生します。このイベントは System.Windows.Forms.DragEventArgs クラスの引数を渡します。この引数の Effect プロパティは、操作がこのコントロール上で終了したときに実行されるアクションを指定する表 1 の値に設定しなくてはなりません。システムはこの値を使って、表示するドロップ カーソルを選択します。次に例を示します。



Private Sub txtDrop_DragEnter(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.DragEventArgs) _
 Handles txtDrop.DragEnter

    If (e.Data.GetDataPresent(DataFormats.Text)) Then
        If (e.KeyState And CtrlMask) = CtrlMask Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.Move
        End If
    End If

End Sub
                

この例では、コードは DragEventArgs 引数の KeyState プロパティを調べて、ドラッグ操作の一部として [Ctrl] キーが押されているかどうかを判定します。もし押されていた場合、コントロールはこのドロップをコピーとして受け取り、そうでなければ移動として受け取ります。

DragEnter イベントは、このコントロール上でのドロップが可能であることをユーザーに知らせるビジュアル フィードバックを提供します。ユーザーがこのコントロール上で実際にマウス ボタンを離すと、DragDrop イベントがトリガされます。この場合には、ドロップされたデータの実際の処理を行わなくてはなりません。たとえば、次のプロシージャは、ドロップされたデータをターゲット コントロールに挿入します。



Private Sub txtDrop_DragDrop(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.DragEventArgs) _
 Handles txtDrop.DragDrop
    txtDrop.Text = e.Data.GetData(DataFormats.Text)
End Sub
                

その他のドラッグ アンド ドロップ イベント

ドラッグ アンド ドロップ操作の一部として、ターゲット コントロール上でトリガすることができるイベントとしては、他に DragOver と DragLeave の 2 つがあります。

DragOver イベントは、カーソルが同じコントロールの中で動き続けたときに発生します (MouseMove イベントに似ています)。



Private Sub txtDrop_DragOver(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.DragEventArgs) _
 Handles txtDrop.DragOver
    ・
End Sub
                

DragLeave イベントは、カーソルが潜在的なドロップ ターゲットの外に移動したときに発生します。



Private Sub txtDrop_DragLeave(ByVal sender As Object, _
 ByVal e As System.EventArgs) _
 Handles txtDrop.DragLeave
    ・
End Sub
                

DragLeave イベントでは、DragEventArgs オブジェクトにはアクセスできないことに注意してください。このイベントは、ドロップが起こらなかったときに、ドロップ ターゲットに加えた変更を「クリーンアップ」するのに便利です。たとえば、DragEnter イベントの際にターゲット コントロールを強調表示し、DragLeave イベントの際に強調表示を削除します。

アプリケーション間のドラッグ アンド ドロップ

アプリケーション間でのドラッグ アンド ドロップには、特殊な操作は必要ありません。DoDragDrop メソッドでドラッグ アンド ドロップ操作を開始したら、ユーザーは同じアプリケーションまたは他の任意のアプリケーションの中にターゲットをドロップすることができます。アプリケーション間のドラッグ アンド ドロップ操作を成功させるために満たさなくてはならない条件は、次の 2 つだけです。


  1. ドロップ ターゲットは、DoDragDrop メソッド呼び出しで指定されたドラッグ効果のうち、少なくとも 1 つをサポートしていなくてはなりません。
  2. ドロップ ターゲットは、ドラッグ コントロールが提供している形式で、データを受け付けなくてはなりません。

ドラッグ アンド ドロップの実装の練習

次の例では、単純な Windows フォーム コンポーネントの中に、コントロール間のドラッグ アンド ドロップを実装します。アプリケーション内でデータをドラッグし、その後、このアプリケーションのデータを別の Windows アプリケーションにドラッグします。

ドラッグ アンド ドロップのテスト用のプロジェクトを作成するには


  1. Visual Studio .NET を開き、スタート ページから [新しいプロジェクト] を選択します。
  2. 画面の左側のツリー ビューから [Visual Basic プロジェクト] を選択します。
  3. プロジェクト テンプレートとして [Windows アプリケーション] を選択します。
  4. アプリケーションの名前を DragDrop に設定し、[OK] をクリックしてプロジェクトを作成します。
  5. [ソリューション エクスプローラ] ウィンドウで Form1.vb という名前のフォームを強調表示し、その名前を frmDragDrop.vb に変更します。
  6. 表 2 の内容に従って、フォームにコントロールを追加し、これらのコントロールのプロパティを設定することで、図 1 のフォームを作成します。



    表 2: frmDragDrop.vb のコントロール



    コントロール タイププロパティ
    TextBoxNametxt1
     Text(ブランク)
    TextBoxNametxt2
     Text(ブランク)
    TextBoxNametxt3
     Text(ブランク)
    TextBoxNametxt4
     Text(ブランク)
    ListBoxNamelboTarget
     AllowDropTrue


    ms973845.dragndropops01(ja-jp,MSDN.10).gif

    図 1. ドラッグ アンド ドロップのテスト用フォーム

ドラッグ アンド ドロップを実装するコードの追加

これで、このフォームの中でドラッグ アンド ドロップ操作を実行するためのコードを書く準備ができました。ここでは、4 つのテキスト ボックスにランダムな値を生成するコードを作成し、テキスト ボックスからリスト ボックスへのドラッグ アンド ドロップを実装します。リスト ボックスのコードは、値のドラッグの際に [Ctrl] キーが押されていればドラッグをコピーとして扱い、そうでなければ移動として扱います。

[表示] メニューの [コード] をクリックして、Windows Form Designer が生成したコードの前に次のコードを入力します。



Const CtrlMask = 8
Private SourceControl As TextBox
                

次に、Windows Form Designer が生成したコードの後に次のコードを入力します。



Private Sub Form1_Load(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles MyBase.Load
    Randomize()
    txt1.Text = Int(Rnd(1) * 10) + 1
    txt2.Text = Int(Rnd(1) * 10) + 1
    txt3.Text = Int(Rnd(1) * 10) + 1
    txt4.Text = Int(Rnd(1) * 10) + 1
End Sub

Private Sub txt1_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles txt1.MouseDown
    If Len(txt1.Text) > 0 Then
        SourceControl = txt1
        txt1.DoDragDrop(txt1.Text, _
         DragDropEffects.Copy Or DragDropEffects.Move)
    End If
End Sub

Private Sub txt2_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles txt2.MouseDown
    If Len(txt2.Text) > 0 Then
        SourceControl = txt2
        txt2.DoDragDrop(txt2.Text, _
         DragDropEffects.Copy Or DragDropEffects.Move)
    End If
End Sub

Private Sub txt3_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles txt3.MouseDown
    If Len(txt3.Text) > 0 Then
        SourceControl = txt3
        txt3.DoDragDrop(txt3.Text, _
         DragDropEffects.Copy Or DragDropEffects.Move)
    End If
End Sub

Private Sub txt4_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles txt4.MouseDown
    If Len(txt4.Text) > 0 Then
        SourceControl = txt4
        txt4.DoDragDrop(txt4.Text, _
         DragDropEffects.Copy Or DragDropEffects.Move)
    End If
End Sub

Private Sub lboTarget_DragEnter( _
 ByVal sender As System.Object, _
 ByVal e As System.Windows.Forms.DragEventArgs) _
 Handles lboTarget.DragEnter
    If (e.Data.GetDataPresent(DataFormats.Text)) Then
        If (e.KeyState And CtrlMask) = CtrlMask Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.Move
        End If
    End If
End Sub

Private Sub lboTarget_DragDrop( _
 ByVal sender As System.Object, _
 ByVal e As System.Windows.Forms.DragEventArgs) _
 Handles lboTarget.DragDrop
    lboTarget.Items.Add(e.Data.GetData(DataFormats.Text))
    If (e.KeyState And CtrlMask) <> CtrlMask Then
        SourceControl.Clear()
    End If
    SourceControl = Nothing
End Sub
                

このコードは次の処理を行っています。


  • Form Load イベントの中のコードは、乱数を使って、4 つのテキスト ボックスに適当なデータを格納します。
  • 個々のテキスト ボックスは、MouseDown イベントをチェックして、テキスト ボックスにデータがあるかどうかをチェックします。データがあれば、DoDragDrop メソッドを呼び出してドラッグ アンド ドロップ操作を開始し、モジュール レベルの SourceControl に自分自身への参照を設定します。
  • リスト ボックスの DragEnter イベントは、KeyState プロパティをチェックして、[Ctrl] キーが押されているかどうかをチェックします。押されていればコピー ドロップ カーソルを表示し、そうでなければ移動ドロップ カーソルを表示します。
  • リスト ボックスの DragDrop イベントは、ドラッグからデータを受け取り、これをリスト ボックスに追加します。また、[Ctrl] キーが押されたままであれば、データのソースだったコントロールをクリアします。

試してみてください

ドラッグ アンド ドロップが実際に動作している様子を確認するには、次の操作を行います。


  1. [F5] キーを押して、プロジェクトを起動します。
  2. カーソルを最初のテキスト ボックス コントロールに置き、マウス ボタンをクリックして押したままにし、マウスの移動を開始します。ドラッグが行われているが、ドロップ ターゲットには入っていないことを示す「ノー ドロップ」シンボルが表示されます。
  3. カーソルをリスト ボックスにドラッグします。カーソルは移動ドロップ シンボルに変化します。
  4. マウス ボタンを離します。最初のテキスト ボックスの値がリスト ボックスに追加され、テキスト ボックスがクリアされます。
  5. カーソルを第 2 のテキスト ボックス コントロールに置き、[Ctrl] キーを押しながらマウス ボタンを押し下げ、マウスの移動を開始します。ドラッグが行われているが、ドロップ ターゲットには入っていないことを示す「ノー ドロップ」シンボルが表示されます。
  6. カーソルをリスト ボックスにドラッグします。カーソルはコピー ドロップ シンボルに変化します。
  7. マウス ボタンを離します。第 2 のテキスト ボックスの値がリスト ボックスに追加されますが、テキスト ボックスはクリアされません。
  8. [スタート] メニューの [プログラム] - [アクセサリ] - [ワードパッド] をクリックして、ワードパッドを起動します。frmDragDrop フォームとワードパッドの両方が見えるように画面を調整します。
  9. カーソルを第 3 のテキスト ボックス コントロールに置き、マウス ボタンをクリックして押したままにし、マウスの移動を開始します。ドラッグが行われているが、ドロップ ターゲットには入っていないことを示す「ノー ドロップ」シンボルが表示されます。
  10. カーソルをリスト ボックスにドラッグします。カーソルはコピー ドロップ シンボルに変化します。ワードパッドは移動ドロップを実装していないので、[Ctrl] キーを押していない場合でもコピー ドロップが行われることに注意してください。
  11. マウス ボタンを離します。第 3 のテキスト ボックスの値がワードパッドに追加されますが、テキスト ボックスはクリアされません。

要約

Windows フォームの世界のすべてのコントロールは、究極的には System.Windows.Forms.Control クラスから派生しているため、ドラッグ アンド ドロップの実装方法はすべてのコントロールで共通しています。このため、Visual Basic .NET でのドラッグ アンド ドロップ コードの作成はきわめて簡単になっています。ドラッグ側では、適切なイベント (通常は MouseDown) が発生したときに DoDragDrop メソッドを呼び出すだけです。ドロップ側では、AllowDrop プロパティを True に設定し、DragEnter および DragDrop イベントを処理します。少し練習するだけで、必要が生じたときにはいつでも簡単にドラッグ アンド ドロップのコードを書けるようになるでしょう。

執筆者について

Mike Gunderloy は Washington 州東部でソフトウェアに関する執筆とニワトリの飼育を行っています。Sybex から出版されている『Access 2002 Developer's Handbook』の共著者であり、『SQL Server Developer's Guide to OLAP with Analysis Services』の著者でもあります。彼は Windows 以前の時代から Microsoft プロダクト関連のコードを書いており、今後もこれを続けていく予定です。

Informant Communications Group について

Informant Communications Group, Inc. (www.informant.com) は、情報テクノロジ セクタに焦点を当てた多角的なメディア会社です。1990 年に創設された ICG は、ソフトウェア開発関連の出版事業、カンファレンス、カタログの発行、および Web サイトを専門としています。米国と英国にオフィスを持つ ICG は、有名なメディアおよびマーケティング コンテンツ インテグレータとして、IT プロフェッショナルに対して高品質の技術情報を提供してきました。


この情報は役に立ちましたか。
(残り 1500 文字)