エクスプローラからファイルをドラッグ&ドロップできるようにするには?[C#、VB].NET TIPS

» 2007年11月29日 05時00分 公開
[遠藤孝信デジタルアドバンテージ]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「.NET TIPS」のインデックス

連載目次

 ファイルを扱うWindowsアプリケーションでは、エクスプローラからのドラッグ&ドロップ(以下、D&D)に対応することで、対象となるファイルの指定を簡単に行えるようにできる。

 エクスプローラからファイルのD&Dを受け付けるようにするには、最低限、次の3つの作業を行えばよい。

  1. フォームのAllowDropプロパティをTrueに設定する
  2. フォームのDragEnterイベント・ハンドラを記述する
  3. フォームのDragDropイベント・ハンドラを記述する

 以下では、2と3のイベント・ハンドラでの記述内容について解説する。

 ちなみに、Visual Studioでフォームにイベント・ハンドラを追加するには、[プロパティ]ウィンドウの[イベント]ボタンをクリックしてイベント一覧を表示し、「DragEnter」や「DragDrop」の欄をマウスでダブルクリックすればよい。

DragEnterイベント・ハンドラの記述

 DragEnterイベントは、ファイルをドラッグ中のマウス・カーソルがフォーム上に入ったときに発生する。

 このときには、次のリスト1のように、ドラッグ中のデータ(e.Data)の形式がファイル(DataFormats.FileDrop)であることをGetDataPresentメソッドにより確認し、もしそうであれば、受け付けるドロップ操作(e.Effect)としてコピー(DragDropEffects.Copy)を設定する。

private void Form1_DragEnter(object sender, DragEventArgs e)
{
  if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
    e.Effect = DragDropEffects.Copy;
  }
}

Private Sub Form1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles MyBase.DragEnter

  If e.Data.GetDataPresent(DataFormats.FileDrop) Then
    e.Effect = DragDropEffects.Copy
  End If

End Sub

リスト1 DragEnterイベント・ハンドラの記述例(上:C#、下:VB)

 このコードにより、ファイルをドラッグ中のマウス・カーソルには「+」マークが表示され、アプリケーションへのファイルのドロップが可能であることを示すようになる。「e.Effect」の初期値は「DragDropEffects.None」であるが、ここではこれ以外の値を設定しないと後続のDragDropイベントは発生しない。

 ただし、リスト1のコードはエクスプローラからフォルダがドロップされた場合にも「+」マークが表示され、ドロップを受け付けてしまう。

 厳密にファイルのみをドロップ可能にするには、次のリスト2のようにして、ドラッグ中のデータがすべてファイルかどうかをチェックする必要がある。

private void Form1_DragEnter(object sender, DragEventArgs e)
{
  if (e.Data.GetDataPresent(DataFormats.FileDrop)) {

    // ドラッグ中のファイルやディレクトリの取得
    string[] drags = (string[])e.Data.GetData(DataFormats.FileDrop);

    foreach (string d in drags)
    {
      if (!System.IO.File.Exists(d))
      {
        // ファイル以外であればイベント・ハンドラを抜ける
        return;
      }
    }
    e.Effect = DragDropEffects.Copy;
  }
}

Private Sub Form1_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter

  If e.Data.GetDataPresent(DataFormats.FileDrop) Then

    ' ドラッグ中のファイルやディレクトリの取得
    Dim drags() As String = _
          CType(e.Data.GetData(DataFormats.FileDrop), String())

    For Each d As String In drags
      If Not System.IO.File.Exists(d) Then
        ' ファイル以外であればイベント・ハンドラを抜ける
        Return
      End If
    Next

    e.Effect = DragDropEffects.Copy
  End If

End Sub

リスト2 ファイルのみを受け付けるDragEnterイベント・ハンドラの記述例(上:C#、下:VB)

 リスト1では、ドラッグ中のデータの形式を確認するのにGetDataPresentメソッドを使用したが、そのデータの内容を取得する場合にはGetDataメソッドを使用する。このメソッドの戻り値の型はObject型だが、データがファイル形式の場合(パラメータにDataFormats.FileDropを指定した場合)には、戻り値はファイルやディレクトリのパス(文字列)の配列となるので、文字列配列へのキャストが必要となる。

 文字列がファイルのパスかどうかを確認するには、そのパスが示すものがファイルとして存在するかを確認すればよい。ここではFileクラス(System.IO名前空間)のExitsメソッドを使用しているが、これについては「TIPS:ファイルやディレクトリの存在を確認するには?」を参照してほしい。

DragDropイベント・ハンドラの記述

 DragEnterイベントに続いては、マウスのボタンが離されたときにDragDropイベントが発生し、D&D操作が完了となる。

 このイベント・ハンドラでは、D&Dされたデータ(=パスの配列)をフィールドに保存したり、各ファイルを開いたりする処理を記述する。次のコードでは、それをリストボックス(listBox1)に表示している。D&Dされたデータの内容の取得はリスト2とまったく同様に、GetDataメソッドにより行える。

private void Form1_DragDrop(object sender, DragEventArgs e)
{
  // ドラッグ&ドロップされたファイル
  string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

  listBox1.Items.AddRange(files); // リストボックスに表示
}

Private Sub Form1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles MyBase.DragDrop

  ' ドラッグ&ドロップされたファイル
  Dim files() As String = _
        CType(e.Data.GetData(DataFormats.FileDrop), String())

  ListBox1.Items.AddRange(files) ' リストボックスに表示

End Sub

リスト3 DragDropイベント・ハンドラの記述例(上:C#、下:VB)
フォーム上にはListBoxコントロール(listbox1)が配置されているものとする。

 DragDropイベントの前には必ずDragEnterイベントが処理されるので、GetDataメソッドにより得られる配列の内容は、DragEnterイベント・ハンドラとDragDropイベント・ハンドラで同じになるはずである。

 最後に1つ注意点であるが、DragEnterイベント・ハンドラやDragDropイベント・ハンドラの処理中には、ドラッグ元となったエクスプローラは応答しなくなる(フリーズ状態となる)。このためイベント処理はできる限り軽くした方がよい。

 DragDropイベント・ハンドラ内で時間のかかる処理を開始したい場合には、BackgroundWorkerコンポーネント(「TIPS:時間のかかる処理をバックグラウンドで実行するには?」を参照)や、スレッドを使用して行う必要がある。

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Windowsフォーム 処理対象:フォーム
使用ライブラリ:DragEventArgsクラス(System.Windows.Forms名前空間)
使用ライブラリ:DragDropEffects列挙体(System.Windows.Forms名前空間)
関連TIPS:ファイルやディレクトリの存在を確認するには?
関連TIPS:時間のかかる処理をバックグラウンドで実行するには?

「.NET TIPS」のインデックス

.NET TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。