Borland のTurbo C++環境でこれが行われているのを見たことがありますが、私が取り組んでいる C# アプリケーションでそれを行う方法がわかりません。注意すべきベスト プラクティスや落とし穴はありますか?
10 に答える
サンプルコード:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(Form1_DragEnter);
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
void Form1_DragDrop(object sender, DragEventArgs e) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files) Console.WriteLine(file);
}
}
Windows Vista / Windows 7のセキュリティ権限に注意してください。VisualStudioを管理者として実行している場合、Visual Studio内から実行すると、管理者以外のエクスプローラーウィンドウからプログラムにファイルをドラッグすることはできません。ドラッグ関連のイベントは発生しません!これが他の誰かが彼らの人生の時間を無駄にしないのに役立つことを願っています...
Windowsフォームで、コントロールのAllowDropプロパティを設定してから、DragEnterイベントとDragDropイベントをリッスンします。
イベントが発生したら、DragEnter
引数AllowedEffect
をnone以外に設定します(例e.Effect = DragDropEffects.Move
)。
イベントが発生するDragDrop
と、文字列のリストが表示されます。各文字列は、ドロップされるファイルへのフルパスです。
落とし穴に注意する必要があります。ドラッグアンドドロップ操作でDataObjectとして渡すクラスは、 Serializableである必要があります。したがって、オブジェクトを渡そうとしても機能しない場合は、シリアル化できることを確認してください。これはほぼ確実に問題です。これは私を数回捕まえました!
さらに別の落とし穴:
ドラッグ イベントを呼び出すフレームワーク コードは、すべての例外を飲み込みます。イベント コードはスムーズに実行されていると思われるかもしれませんが、あちこちで例外が発生しています。フレームワークがそれらを盗むため、それらを見ることはできません。
そのため、これらのイベント ハンドラーに常に try/catch を入れて、例外がスローされるかどうかを確認しています。私は通常、Debugger.Break(); を配置します。キャッチ部分に。
リリース前、テスト後、すべてが動作しているように見える場合は、これらを削除するか、実際の例外処理に置き換えます。
もう1つの一般的な落とし穴は、Form DragOver(またはDragEnter)イベントを無視できると考えていることです。私は通常、フォームのDragOverイベントを使用してAllowedEffectを設定し、次に特定のコントロールのDragDropイベントを使用してドロップされたデータを処理します。
これは、ファイルやファイルでいっぱいのフォルダーをドロップするために使用したものです。私の場合、*.dwg
ファイルのみをフィルタリングし、すべてのサブフォルダーを含めることを選択しました。
fileList
私のIEnumerable
場合、WPFコントロールにバインドされていました...
var fileList = (IList)FileList.ItemsSource;
そのトリックの詳細については、https://stackoverflow.com/a/19954958/492を参照してください。
ドロップハンドラー ...
private void FileList_OnDrop(object sender, DragEventArgs e)
{
var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
var files = dropped.ToList();
if (!files.Any())
return;
foreach (string drop in dropped)
if (Directory.Exists(drop))
files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));
foreach (string file in files)
{
if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
fileList.Add(file);
}
}