上へ W0001 時間を自動計測する W0101 MDIメニュー W0102 外部とのドラッグ&ドロップ
| |
VB.NET2005 TIPS / ウィンドウズ系 |
W0102 外部とのドラッグ&ドロップ |
最終更新:2006/11/12 統合再掲 |
●解説
昔、OLEDragDropと言っていたもの。.NETでは
アプリ内外の区別がなくなり、方式も変更されている。他のアプリケーション(IE(インタネット)、一般的な画像表示アプリ(Word、PDFアプリ)、ファイルエクスプローラなど)
とで、
単数ないし複数の画像やファイルをDrag&Dropする。 外部と題しているが内部でも一向に構わない。
全く相互が限定されていて暗黙的であるなら、この形式は自由で良いが、一応、Windowsのルールに従った方法を紹介する。
●原理
Dataオブジェクトにて形式を確定して、D&Dする。代表的なデータ形式は以下の通り。
-
DataFormats.FileDrop :ファイルリスト(ファイルパスを入れた配列)
-
DataFormats.Bitmap :ビットマップそのもの
-
DataFormats.Text :ANSI文字列
●方法
○クライアント
(情報を受け取る側)
-
フォームなどをターゲットとする。AllowDropをTrueにして置く。
-
DragOverイベントでデータ形式をチェックし反応する。
OKかNGで、これによりマウスカーソル形状が自動的に変化する。
-
DragDropイベントでデータ形式をチェックし、OKなら受け取る。
-
自分がサーバになっている場合もあるので、注意方。
○サーバ (情報を送る側)
-
フォーム
などにてユーザがマウスダウンし、ある程度の距離のドラッグがあればD&Dを開始させるなどする。
→マウスダウンのみで開始すると他のUI処理ができなくなる。
-
ドラッグすべき情報のリストを作成し、そのリストをDataオブジェク化し、適当なコントロールにてD&Dを発行(DoDragDrop)する。あとは、相手次第。
→適当なコントロール:何でも良い。ダミーでもOK
-
ファイルの移動であるなら、完了イベント(GiveFeedback)にて、元のファイルを削除など行う。
-
自分がクライアントでもあるなら、自身の情報も処理する必要がある。受け入れないとか、内部フォーム間での移動などの処理。
●実例
○クライアント
この例では、PictureBox(picM)をターゲットで、
画像のコピーのみ可能の場合。
Private Sub
picM_DragOver(ByVal sender As Object, ByVal e As
System.Windows.Forms.DragEventArgs) Handles picM.DragOver
If
e.Data.GetDataPresent(DataFormats.FileDrop, False)
Then
e.Effect =
DragDropEffects.Copy
'FileDropならコピー可能を知らせる
ElseIf
e.Data.GetDataPresent(DataFormats.Bitmap, False)
Then
e.Effect =
DragDropEffects.Copy
'あるいはBitmapならコピー可能を知らせる
Else
e.Effect =
DragDropEffects.None
'これによりマウスカーソルは禁止マークとなる
End If
End Sub
Private Sub
picM_DragDrop(ByVal sender As Object, ByVal e As
System.Windows.Forms.DragEventArgs) Handles picM.DragDrop
If e.Data.GetDataPresent(DataFormats.FileDrop, False)
Then
Dim s() As String = e.Data.GetData(DataFormats.FileDrop,
False) 'ファイルのパス一覧を得る
Dim ff, i As Integer, fp, FN As String
Dim fi As FileInfo, bmp As Bitmap
Me.Cursor = Cursors.WaitCursor
ff = 0
For i = 0 To s.Length - 1
fp = s(i)
fi = New FileInfo(fp)
Select Case fi.Extension 'ファイル拡張子をチェックする
Case ".bmp", ".jpg", ".jpeg", ".gif", ".tif", ".png"
(bmp = Bitmap.FromFile(fp))
・・・・・・・・・・・・・・・・・・
'必要な処理をする。受け取った画像の保存、表示など
ff = ff + 1
Case Else
'NOP
End Select
Next
If ff > 0 Then
・・・・・・・・・・・・・・・・・・・・・・
Me.Cursor = Cursors.Default
Else
Me.Cursor = Cursors.Default
MsgBox("有効なファイルがありませんでした。", MsgBoxStyle.Critical)
End If
ElseIf e.Data.GetDataPresent(DataFormats.Bitmap,
False) Then
Dim bmp As
Bitmap = e.Data.GetData(DataFormats.Bitmap, False)
'画像を獲得する
・・・・・・・・・・・・・・・・・・
'必要な処理をする。受け取った画像の保存、表示など
End
If
End Sub
○サーバ
ピクチャボックスpicMに複数の画像を代表する画像群が表示されており、その一つに対してマウスダウンがあったとする。
Private Sub picM_MouseDown(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles picM.MouseDown
dX = e.X
dY = e.Y
'ダウン座標を記憶
If (特定の画像の上) Then
(ドラッグ開始可能とする。)
Else
(ドラッグなしとする。)
End If
End Sub
Private Sub picM_MouseMove(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles picM.MouseMove
If e.Button = MouseButtons.Left And (ドラッグ可能) Then
If Abs(e.X -
dX) > 20 And Abs(e.Y - dY) > 20 Then
'ある程度移動したか?
Dim s() As
String
Dim d As New
DataObject()
'D&DのDataオブジェクト
s() =
(画像のパスのリストを作成)
d.SetData(DataFormats.FileDrop, False, s) 'インスタンスに形式を登録
picM.DoDragDrop(d,DragDropEffects.Copy) 'メソッドを発行
End If
End If
End Sub
→DataFormats.FileDrop
を他の形式にすれば、その形式でD&Dできる。
|