C#のWPFでファイル名をドラッグ&ドロップで受け取る

Windowsにはドラッグ&ドロップという操作があります。

エクスプローラなどでファイルを選択し、選択したファイルをドラッグして別のアプリの上に持ってくると、そのアプリで選択したファイルが開けたりといった機能です。

 

WPFを使うとそんなドラッグ&ドロップに対応したアプリを簡単に作る事ができます。


AllowDropプロパティ

ドラッグ&ドロップでデータを受け取るコントロールの AllowDropプロパティTrue に設定します。

AllowDropプロパティを True にする事で、そのコントロールは Dropイベントを受け取れるようになります。

 

以下の例ではDropイベントとDragOverイベントも追加しています。

<Window x:Class="WpfTest1.TestWindow1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfTest1"
        mc:Ignorable="d"
        Title="TestWindow1" Height="300" Width="300">
    <Grid>
        <ListBox x:Name="FileListBox" Margin="10"
                    AllowDrop="True"
                    Drop="FileListBox_Drop"
                    DragOver="FileListBox_DragOver">
        </ListBox>
    </Grid>
</Window>

Dropイベントを実装する

Dropイベントでドラッグ&ドロップされたデータを受け取ります。

 

ドラッグ&ドロップ操作で受け取れるデータ形式には様々な種類があります。

Dropイベントの引数にある DragEventArgs クラスのDataプロパティには受け取ったデータが格納されていますが、その GetDataPresentメソッドを使うとデータ形式の種類を判別できます。

 

種類を判別したあと、GetDataメソッドを使ってデータを取得します。

データ形式がファイルの場合は string型の配列としてデータを受け取る事になります。


DragOverイベント

DragOverイベントはドラッグしてきたマウスがコントロールの中に入った時のイベントです。

 

下記の例ではデータ形式がファイルの時だけデータを受けっていて、それ以外の形式の場合は無視しています。

AllowDropプロパティを True にするとドラッグされた時にマウスカーソルが変化するようになりますが、このアプリが受け取れるデータ形式の時だけマウスカーソルが変化させる方が親切です。

 

DragOverイベントを使って、受け取れるデータ形式の時のみマウスカーソルを変えるよう制御しましょう。

using System.Collections.ObjectModel;
using System.Windows;

namespace WpfTest1
{
    public partial class TestWindow1 : Window
    {
        private ObservableCollection<string> FileList;


        public TestWindow1()
        {
            InitializeComponent();
            FileList = new ObservableCollection<string>();
            FileListBox.ItemsSource = FileList;
        }

        private void FileListBox_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                var fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
                foreach (var name in fileNames)
                {
                    FileList.Add(name);
                }
            }
        }

        private void FileListBox_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effects = DragDropEffects.All;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
            e.Handled = true;
        }
    }
}