Home > C# > WPF > イベント > ドラッグ&ドロップ > TextBoxへのドロップ操作でファイル名を取得する

TextBoxへのドロップ操作でファイル名を取得する C# WPF

新規作成日 2019-09-11
最終更新日

C# WPFで行うドラッグ&ドロップ操作

ドラッグ&ドロップは、オブジェクトをマウス操作で、移動する操作のことです。

ドラッグ&ドロップ

ドラッグ元のし要素上で、マウスの左ボタンを押したままマウスを動かし、ドロップ先にマウスカーソルが移動したところで、マウスの左ボタンを離します。この操作で、ドラッグ元の要素をドロップ先に移動、あるいは、ドラッグ元の要素を選択できます。

参考

TextBoxへのドロップ操作でファイル名を取得する

ファイル名を取得する方法には、オープン・ファイル・ダイアログを使用する方法に加えて、ドラッグ&ドロップがあります。コードを記述する場合、オープン・ファイル・ダイアログを使用する方法の方が明瞭です。アプリケーションを実際に操作する際は、感覚的に、ドラッグ&ドロップ操作のほうが明瞭です。

そのため、アプリケーションの操作性を考えると、どちらかだけを実装するのではなく、両方実装することが求められます。

C#のユーザーインターフェイスの実装には、Formアプリケーション、WPFアプリケーション、UWP、Xamarinが使われています。それぞれに実装方法、具体的には使用するクラスが異なります。そのため、MVVMと呼ばれる、表示と入力部分を独立させるデザインパターンの使用が推奨されています。興味があれば、導入を検討してみてください。

今回、C# WPFを用いで、ファイルをドラッグ&ドロップすることにより、ファイル名を取得するコードを確認してみたいと思います。

参考

C# WPFで、TextBoxにファイルをドロップしてファイル名を取得する場合、TextBoxがもともとドラッグ&ドロップに対応しているため、ドロップのためのイベントの内容を記述する他に、イベントハンドラを追加する作業が必要です。

ドロップしたファイルのファイル名を表示するテキストボックス

WPFアプリ(.Net Framework)で、プロジェクトを新規作成します。

MainWindow.xamlに以下のコードを入力し、UIを作成します。

<Window x:Class="GetFileName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        
        Title="MainWindow" Height="150" Width="350">
    <DockPanel>
        <Grid DockPanel.Dock="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0">Button01</Button>
            <Button Grid.Column="1">Button02</Button>
        </Grid>
        <TextBox DockPanel.Dock="Top" Name="tb" TextWrapping="Wrap" AllowDrop="True" >
            TextBox
        </TextBox>
    </DockPanel>
    
</Window>

ドロップを有効にするために、AllowDrop="True" に、テキストを折り返すために、TextWrapping="Wrap"属性を追加します。(注 Textboxは、ドラッグ&ドロップをすでに実装しているため、AllowDrop="True" を追加する必要はありません。)

参考

DragOver イベントでは、ドラッグされている要素が、目的の要素であるかを確認し、目的の要素の場合のみ処理を行います。

ドラッグされている要素が、目的の要素であるかは、以下のコードで確認することができます。

e.Data.GetDataPresent(DataFormats.FileDrop)

要素の種類は、 DataFormatsで指定します。ここでは、ファイルであることを確認するために、FileDropを指定しています。

参考

DragOverイベントでは、ドラッグされている要素の内容に合わせて、マウスポインタを変更します。

DragOver イベントは、ドラッグした状態でマウスポインタが、要素上にあるときイベントが発生し続けるので、イベント処理の最後で、 e.Handled = false;を記述しイベントをクリアします。

private void Tb_DragOver(object sender, DragEventArgs e)
{
    // マウスポインタを変更する。
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        e.Effects = DragDropEffects.All;
    }
    else
    {
        e.Effects = DragDropEffects.None;
    }
    e.Handled = false;
}
参考

次に、Dropイベントを追加します。

private void Tb_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormats.FileDrop))
    {
        // TextBoxの中身をクリアする。
        tb.Text = string.Empty;
        // ドロップしたファイル名を全部取得する。
        string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop);
        // 最初のファイルをTextBoxで
        tb.Text = filenames[0];
    }
}

ファイルのドロップは、e.Data.GetData(DataFormats.FileDrop)で、オブジェクト型として取得できます。

ファイル名を取得する場合は、string型の配列として取得します。

残念ながら、これだけでは、ドラッグ&ドロップ操作で、ファイルをドロップすることで、ファイル名をTextBoxに表示することはできません。

WPFのTextBox、RichTextBox、FlowDocumentコントーロールは、ドラッグ&ドロップ機能が組み込まれています。テキストを他のアプリケーションとの間で、ドラッグ&ドロップできます。

今回のように、ファイルをドロップして、TextBoxにファイル名を表示させる機能は、新たに追加する機能になります。このように、ドラッグ&ドロップ機能を持っている、これら3つのコントロールに、ドラッグ&ドロップ機能を追加するには、明示的に、AddHandler(RoutedEvent, Delegate, Boolean)メソッドを使用して、イベントハンドラを追加する必要があります。

参考

MainWindow()メソッドに、イベントハンドラを追加します。

public MainWindow()
{
    InitializeComponent();

    tb.AddHandler(TextBox.DragOverEvent, new DragEventHandler(Tb_DragOver), true);
    tb.AddHandler(TextBox.DropEvent, new DragEventHandler(Tb_Drop), true);

}

コード全体を示します。

MainWindow,xaml

<Window x:Class="GetFileName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        
        Title="MainWindow" Height="150" Width="350">
    
    <DockPanel>
        <Grid DockPanel.Dock="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0">Button01</Button>
            <Button Grid.Column="1">Button02</Button>
        </Grid>
        <TextBox DockPanel.Dock="Top" Name="tb" DragOver="Tb_DragOver" Drop="Tb_Drop" AllowDrop="True" TextWrapping="Wrap">
            TextBox
        </TextBox>
    </DockPanel>
    
</Window>

MainWindow,xaml.cs

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

namespace GetFileName
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            tb.AddHandler(TextBox.DragOverEvent, new DragEventHandler(Tb_DragOver), true);
            tb.AddHandler(TextBox.DropEvent, new DragEventHandler(Tb_Drop), true);

        }

        private void Tb_DragOver(object sender, DragEventArgs e)
        {
            // マウスポインタを変更する。
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effects = DragDropEffects.All;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
            e.Handled = false;
        }

        private void Tb_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // TextBoxの中身をクリアする。
                tb.Text = string.Empty;
                // ドロップしたファイル名を全部取得する。
                string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop);
                tb.Text = filenames[0];
            }
        }
    }
}

TextBoxへのドロップ操作でファイル名を取得する

このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」