C#プログラミングTipsエクスプローラからのドラッグ&ドロップを受け付けるにはデジタルアドバンテージ |
Windowsアプリケーションでファイルを開く場合、マウスを使ったドラッグ&ドロップは、最も直感的で便利な方法だ。しかしなぜか、.NET Frameworkのドキュメントを見ても、この方法が明記されていない。そこで今回は、エクスプローラで選択したファイルのドラッグ&ドロップをWindowsアプリケーションで受け取る方法をご紹介する。
まずは、今回作成するサンプル・プログラムの全コードを示す。
|
|
dragdrop.csのソースコード | |
このプログラムを実行すると、以下の画面のように、クライアント領域いっぱいにリストボックスが貼り付けられたウィンドウが表示される。
今回作成したサンプル・プログラムを実行したところ |
今回のサンプル・プログラムを起動すると、このようにウィンドウのクライント領域いっぱいにリストボックスが貼り付けられたウィンドウが表示される。 |
この状態で、エクスプローラからいくつかのファイルをマウスで選択し、このウィンドウの上までドラッグすると、次の画面のように、このウィンドウがドラッグ&ドロップを受け付けることを示す十字マークがマウスのポインタに表示される。
エクスプローラでファイルを選択し、それらをマウスでドロップする | ||||||
エクスプローラでファイルを選択して、それらをマウスで今回のウィンドウまでドラッグする。この場合マウス・ポインタには、直下にあるアプリケーションがドロップを受け付けることを示す「+マーク」が表示される。 | ||||||
|
そしてマウスのボタンを離すと、次の画面のように選択していたすべてのファイルのフルパスがリストボックスに列挙される。このサンプル・プログラムの処理はここまでだが、こうしてファイルのフルパスさえ取得できれば、さまざまなアプリケーションで応用できるだろう。
ファイル・アイコンをドロップしたところ | |||
エクスプローラからドラッグしたファイル・アイコンをサンプル・プログラム上でドロップしたところ。するとこのように、ドラッグしたファイルのフルパスがリストボックスに表示される。 | |||
|
ドラッグ&ドロップ処理では2つのイベント処理が必要
それではドラッグ&ドロップを実装する手順を解説しよう。アプリケーションでドラッグ&ドロップを受け付けるには、2つのイベントに対応する必要がある。ファイルをドラッグした状態でマウスがウィンドウの領域に入ったときに発生するDragEnterイベントと、それに続いてマウスのボタンを離したときに発生するDragDropイベントの2つである。DragDropイベントが発生した時点でドラッグ&ドロップの操作は完了するので、このときにイベントとともに送られてくるデータ(選択されたファイル名が含まれているはず)を取得すればよい。
AllowDropプロパティの設定
ところで、これら2つのイベントをどこで受け取ればよいだろうか? アプリケーションのウィンドウ全体にあたるフォームでも受け取り可能だが、これらのイベントはマウス・カーソルがある直下のコントロールにのみ送られる。今回はリストボックスをフォーム全体に配置しているので、このリストボックス・コントロールがドラッグ&ドロップを受けるようにした。これにはまず、リストボックスのAllowDropプロパティをtrueに設定しておく(29行目)。
29: listbox1.AllowDrop = true; |
DragEnterイベント・ハンドラ
次のコードは、最初に送られてくるDragEnterイベントに関する部分を抜き出したものだ。ここではまず、DragEnterイベントに対応するイベント・ハンドラとなるメソッド(ここではlistbox1_DragEnter)を作成しておき、DragEventHandlerクラスにより作成したインスタンスをリストボックスのDragEnterイベントに追加する(30行目)。イベント・ハンドラを設定するこの手順は、ボタンがクリックされるときに呼び出されるクリック・イベント・ハンドラを設定するのと同じだ(別稿の「Windowsアプリケーションのスケルトンを知る」を参照)。
10: protected void listbox1_DragEnter(object
s, DragEventArgs e) { |
イベント・ハンドラであるlistbox1_DragEnterメソッドでは、このコントロールが受け取ることのできる操作の種類(「コピー」や「移動」などがある)を設定する必要がある。これは2番目の引数であるDragEventArgsオブジェクトのEffectプロパティに、列挙型であるDragDropEffectsのメンバーを指定することによって行う。ここではとりあえずDragDropEffects.Allを指定しておけばよい(11行目)。
DragDropイベント・ハンドラ
DragDropイベント・ハンドラに関する処理は次のコードである。
14: protected void listbox1_DragDrop(object
s, DragEventArgs e) { |
イベント・ハンドラの登録は、上記のDragEnterイベントと同様だ。このイベント・ハンドラではまず、イベントとともに受け取ったデータがファイルをドラッグしているものかどうかをチェックし、もしそうであればそのデータからファイルのフルパス名を文字列の配列として取り出す。チェックが必要な理由は、ドラッグ&ドロップされるものがファイルとは限らないためだ。Windowsでは、選択したテキストやIEのリンクなどもドラッグ&ドロップすることができる。
イベントとともに送られる、ドラッグされたデータはDragEventArgsオブジェクトのDataプロパティに設定される。リスト中にあるe.Dataがそれで、これはDataObjectクラスのオブジェクトである(正確にはe.DataはIDataObjectインターフェイスのインターフェイス・インスタンスであり、DataObjectクラスはIDataObjectインターフェイスを実装したクラスである)。
e.Dataのデータがファイルをドラッグ&ドロップしたものかどうかはGetDataPresentメソッドに引数としてDataFormats.FileDropを指定することによってチェックする(15行目)。DataFormats.FileDropは、ファイル・ドロップのフォーマットを示す。e.Dataのデータがこのフォーマットであれば、GetDataメソッドにより文字列の配列としてファイルのフルパス名を取り出すことができる。C#のforeach文を使用すれば、この配列内の各文字列を順番に1つずつ文字列変数であるfileNameに入れていくことができる(16、17行目)。後は各文字列をリストボックスのアイテムとして追加しているだけだ(18行目)。
リファレンス・マニュアルでDragEventArgsクラスを調べると分かるが、DragEventArgsのプロパティにより、ユーザーによってドロップ処理が実行されたときのキー([Shift]キーや[Ctrl]キー、[Alt]キーなど)の状態や、マウス座標も得ることができる。
プログラムのコンパイル
なお、プログラムのコンパイルは、コマンド・プロンプトから次のコマンドを実行する。
csc /r:Microsoft.Win32.Interop.DLL /r:System.DLL |
コンパイルが成功すればdragdrop.exeができあがる。
「C#プログラミングTips」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|