[C# WPF] エクスプローラからのファイルドラッグ&ドロップ

ファイルをドラッグ&ドロップする処理を実装したい。

という要望が私の中にあったので書きました。

スポンサーリンク

環境

  • Visual Studio 2019
  • .NET Framework 4.7.2

ファイルのドラッグ&ドロップを受け付けるには、UIElementのDropイベントを使用します。

メインウィンドウへのファイルドロップ

ファイルのドロップを実装するだけだったら簡単です。

ドロップするファイルの拡張子によって背景色を変えるサンプルを作りました。

.jpgファイルだと赤に、.pngファイルだと緑に、それ以外は白になります。

・MainWindow.xaml

<Window x:Class="Sample_FileDrop.MainWindow"
        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:Sample_FileDrop"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        AllowDrop="True"
        Drop="Window_Drop">
</Window>

・MainWindow.xaml.cs

using System.Windows;
using System.Windows.Media;

namespace Sample_FileDrop
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Drop(object sender, DragEventArgs e)
        {
            // ファイルドロップを判定する
            if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
            {
                // ドロップしたファイルのパスを取得する
                // 複数の場合があるので配列になります
                var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
                if (paths == null || paths.Length != 1)
                {
                    return;
                }

                // ファイルの拡張子を取得する
                var ext = System.IO.Path.GetExtension(paths[0])?.ToLower();

                switch (ext)
                {
                    case ".png":
                        // 拡張子がPNGだったら,背景色を赤にする
                        Background = Brushes.Red;
                        break;
                    case ".jpg":
                        // 拡張子がJPGだったら,背景色を緑にする
                        Background = Brushes.Green;
                        break;
                    default:
                        // その他の拡張子だったら,背景色を白にする
                        Background = Brushes.White;
                        break;
                }
            }
        }
    }
}

マウスカーソル的には、ウィンドウ内だったら有効、という感じに勝手に動いてくれます。

指定した領域にだけファイルドロップ

次に、ここにもうひとつViewを追加して、その上にだけドロップできるようにします。

MainViewからはファイルドロップ関連の機能を外します。

ドロップ機能は新しく追加したDropViewに移動しています。

・MainView.xaml

<Window x:Class="Sample_FileDrop.MainWindow"
        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:Sample_FileDrop"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        Background="Gray"
        >

    <local:DropView Height="200" Width="400"
                    HorizontalAlignment="Center" VerticalAlignment="Center"
                    Background="White"
                    />

</Window>

・MainView.xaml.cs

using System.Windows;

namespace Sample_FileDrop
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

・DropView.xaml

<UserControl x:Class="Sample_FileDrop.DropView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:Sample_FileDrop"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800"
             AllowDrop="True"
             Drop="DropView_Drop"
             >
</UserControl>

・DropView.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Sample_FileDrop
{
    public partial class DropView : UserControl
    {
        public DropView()
        {
            InitializeComponent();
        }

        private void DropView_Drop(object sender, System.Windows.DragEventArgs e)
        {
            // ファイルドロップを判定する
            if (e.Data.GetDataPresent(DataFormats.FileDrop, true))
            {
                // ドロップしたファイルのパスを取得する
                // 複数の場合があるので配列になります
                var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
                if (paths == null || paths.Length != 1)
                {
                    return;
                }

                // ファイルの拡張子を取得する
                var ext = System.IO.Path.GetExtension(paths[0])?.ToLower();

                switch (ext)
                {
                    case ".png":
                        // 拡張子がPNGだったら,背景色を赤にする
                        Background = Brushes.Red;
                        break;
                    case ".jpg":
                        // 拡張子がJPGだったら,背景色を緑にする
                        Background = Brushes.Green;
                        break;
                    default:
                        // その他の拡張子だったら,背景色を白にする
                        Background = Brushes.White;
                        break;
                }
            }
        }
    }
}

こうすることで、DropViewだけでファイルドロップを受けることができます。

マウスカーソルもMainView側のAlloDropが初期値(False)になっているので、勝手に駐車禁止カーソル(名前がわからん)になってくれます。

おしまい。

スポンサーリンク

C#,WPFC#,WPF

Posted by peliphilo