ファイルをアプリケーションにドラッグアンドドロップする方法を教えてください。


251

これがBorlandのTurbo C ++環境で行われるのを見てきましたが、現在取り組んでいるC#アプリケーションでどのように対処すればよいかわかりません。注意すべきベストプラクティスや落とし穴はありますか?


C#アプリケーションまたはC#IDEにドラッグアンドドロップするということですか?
JamesSugrue 2008

4
もちろん、C#アプリケーション。彼は自分のアプリケーションをドラッグアンドドロップ対応にしたいと考えています。
SLA80 2010

3
リンクでより役立つ回答。
Venkatesh Kumar

回答:


505

いくつかのサンプルコード:

  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);
    }
  }

56
免責事項:Visual Studioを管理者としてWindows 7で実行した場合、またはプログラムを管理者として実行した場合、デバッグで機能しない可能性があります。ここを
Matthieu

ファイルの内容をどのように取得しますか?
Burnsys 2013

3
@Burnsysドラッグ操作からのファイルパスがある場合は、io.File
Smith

1
ううん、違う。デザイナーでAllowDropプロパティをTrueに設定し、そこから推論します。
ハンスパッサント2014

2
(string[])キャストはFileDropフォーマットされたドロップに対して安全ですか?つまりFileDrop、不正なキャスト例外を引き起こすを生成することは可能string[]ですか?私はドキュメントからそれを理解するのに苦労しています。
kdbanman 2015

140

Windows Vista / Windows 7のセキュリティ権限に注意してください。VisualStudioを管理者として実行している場合、Visual Studio内から実行すると、管理者以外のエクスプローラーウィンドウからプログラムにファイルをドラッグできません。ドラッグ関連のイベントは発生しません!これが他の誰かの人生の時間を無駄にしないのに役立つことを願っています...


6
@ウェイン・ウロダ:私のコードは機能していないと思いました-ええと、それはこのen.wikipedia.org/wiki/File:ProhibitionSign2.svgのような大きな「記号なし」を私に与えていました。それから私はこの答えを見て、VSを非管理者として実行しました、そしてそれはうまくいきます!どうもありがとう。
デレクW

本当にありがとうございました。たまたまこの投稿を見つけない限り、私はあきらめたでしょう!これは、あなたが書いたときと同じように、2017年のWindows 10でも有効です。
Culme 2017年

42

Windowsフォームで、コントロールのAllowDropプロパティを設定し、DragEnterイベントとDragDropイベントをリッスンします。

DragEnterイベントが発生したとき、引数をAllowedEffectnone以外に設定します(例:e.Effect = DragDropEffects.Move

ときにDragDropイベントが発生させ、あなたは文字列のリストを取得します。各文字列は、ドロップされるファイルへのフルパスです。


16

あなたは落とし穴を認識する必要があります。ドラッグアンドドロップ操作でDataObjectとして渡すクラスはすべて、シリアル化可能である必要があります。そのため、オブジェクトを渡してみても機能しない場合は、シリアル化できることを確認してください。これがほぼ間違いなく問題です。これは私を数回引っ張り出しました!


14

さらに別の落とし穴:

Drag-eventsを呼び出すフレームワークコードは、すべての例外を飲み込みます。イベントコードはスムーズに実行されていると思われるかもしれませんが、例外はあちこちに発生しています。フレームワークがそれらを盗むため、それらを見ることができません。

そのため、常にこれらのイベントハンドラーにtry / catchを配置し、例外がスローされるかどうかを確認しています。私は通常Debugger.Break();を置きます。キャッチ部分に。

リリース前、テスト後、すべてが動作しているようであれば、これらを削除するか、実際の例外処理に置き換えます。


9

もう1つの一般的な問題は、フォームのDragOver(またはDragEnter)イベントを無視できると考えていることです。通常、フォームのDragOverイベントを使用してAllowedEffectを設定し、次に特定のコントロールのDragDropイベントを使用して、ドロップされたデータを処理します。


7

これは、ファイルやファイルでいっぱいのフォルダをドロップするために使用したものです。私の場合、*.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);
    }
  }

3

Judah HimangoとHans PassantのソリューションはDesignerで利用できます(私は現在VS2015を使用しています):

ここに画像の説明を入力してください

ここに画像の説明を入力してください


0

WinFormsとWPFにドラッグ&ドロップを実装できます。

  • WinForm(アプリウィンドウからドラッグ)

あなたはmousemoveイベントを追加する必要があります:

private void YourElementControl_MouseMove(object sender, MouseEventArgs e)

    {
     ...
         if (e.Button == MouseButtons.Left)
         {
                 DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
         }
     ...
    }
  • WinForm(アプリウィンドウにドラッグ)

DragDropイベントを追加する必要があります。

プライベートvoid YourElementControl_DragDrop(オブジェクト送信者、DragEventArgs e)

    {
       ...
       foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
            {
                File.Copy(path, DirPath + Path.GetFileName(path));
            }
       ...
    }

完全なコードのソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.