Home > C# > WPF > イベント > ドラッグ&ドロップ > Dropで、ファイルを指定して、ファイル名を変更する

Dropで、ファイルを指定して、ファイル名を変更する

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

ファイルに何らかの操作をする際、Drop操作でファイルを選択できると、操作性が良くなります。ファイル名を変更する操作行うアプリケーションを作成します。

参考

Drop操作で、ファイル名を取得する方法については、「TextBoxへのドロップ操作でファイル名を取得する C# WPF」を参照してください。

Windowsアプリケーションで、ファイルの位置を表す方法

ファイル名は、パスとファイル名、拡張子をあわせて取得し、使用します。それぞれを別個に利用したい場合は、別個に取り出す操作が必要です。そして、それぞれを別個に扱う方法は、C#では、システムSystem.IO名前空間のPathクラスに、あらかじめ、用意されています。

Windowsプログラムで使用するファイルの位置を表す表現は、Pathクラスで扱うDosやWindowsシステムで見慣れたパス形式の他に、Uriクラスで扱う、htmlなどネットワーク関連でよく使用されるUri形式があります。

Windowsプログラム内部で使用する場合、パス形式が扱いやすいです。

参考

ファイル名は、パスとファイル名、拡張子をあわせて取得し、使用します。それぞれを別個に利用したい場合は、別個に取り出す操作が必要です。そして、それぞれを別個に扱う方法は、C#では、システムSystem.IO名前空間のPathクラスに、あらかじめ、用意されています。

Windowsプログラムで使用するファイルの位置を表す表現は、Pathクラスで扱うDosやWindowsシステムで見慣れたパス形式の他に、Uriクラスで扱う、htmlなどネットワーク関連でよく使用されるUri形式があります。

Windowsプログラム内部で使用する場合、パス形式が扱いやすいです。

ファイル名から、必要な情報を取り出す

パス形式のファイルの位置を表す文字列から、必要な部分を取り出すには、Pathクラスに用意されているメソッドを使用すると便利です。

参考

複数の情報を連結してファイル名を作成する

分割したファイル名を連結するには、PathクラスのCombine静的メソッドを使用します。静的メソッドなので、new演算子でインタンスを作成することなく使用できます。

ファイル名を変更する

C#でファイル名を変更する方法には、2つの方法があります。

1つは、FileクラスのFile.Move静的メソッドを使用する方法です。

移動先のパスに、移動元と同じ位置を指定することで、名前を変更することができます。

もう一つは、FileInfoクラスのMoveToメソッドを使用する方法です。こちらは、通常のメソッドなので、newコマンドで、インスタンスを生成して使用する必要があります。

このメソッドも、移動先のパスに、移動元と同じ位置を指定することで、名前を変更することができます。

プログラムの作成

TextBoxにファイルをドロップすると、ファイル名を取得するコードを修正して、ファイル名を変更できるプログラムを作成します。

UIとドロップする部分については、「TextBoxへのドロップ操作でファイル名を取得する C# WPF」を参照してください。

MainWindow.xaml

<Window x:Class="ChangeFileName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        
        Title="ファイル名変えちゃうぞ!" Height="150" Width="350">

    <DockPanel>
        <Grid DockPanel.Dock="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Click="Button_Click">ファイル名変更</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.IO;
using System.Windows;
using System.Windows.Controls;

namespace ChangeFileName
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {

        string fname;   // ファイル名(名前と拡張子)
        string newfname; // 変更後のファイル名(フルパス)
        string oldfname; // 変更前のファイル名(フルパス)
        string dir;     // パス

        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;
                // ファイル名をクリア
                fname = null;
                // ディレクトリ名をクリア
                dir = null;

                // ドロップしたファイル名を全部取得する。
                string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop);

                // フルパスファイル名をoldfnameに入れ、メソッドの外からもアクセスできるようにする。
                oldfname = filenames[0];

                // ファイル名と拡張子を取得
                fname = Path.GetFileName(filenames[0]);
                // ディレクトリ名を取得
                dir = Path.GetDirectoryName(filenames[0]);

                tb.Text = fname;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            newfname = Path.Combine(dir, tb.Text);

            // ファイル名を変更する File.Move
            File.Move(oldfname, newfname);
        }
    }
}

実行して動作を確認します。うまく動くようです。

実行して動作を確認します。うまく動くようです。

長すぎるファイル名を持ったファイルを扱ったときの動作

しかし、長すぎるファウル名を持つファイルをドロップするとエラーが発生します。

System.Runtime.InteropServices.COMException: 'システム コールに渡されるデータ領域が小さすぎます。 (HRESULT からの例外:0x8007007A)'

System.Runtime.InteropServices.COMException:

私が持っているアプリケーションでは、「TMPGEnc Video Mastering Works 5」が、エクスプローラーで名前変更できない長いファイルを作成することができます。

フルパスで260文字を超えるファイル名を扱う

調べてみたところ、C#で、フルパスで260文字を超えるファイル名を扱うには、.Net Freameworkに含まれるクラスを使うと実現できないようです。Win32APIを使用して操作する必要があるようです。

必要を感じたら、フルパスで260文字を超えるファイル名を扱うアプリケーションに挑戦してみるかもしれませんが、現時点では、これで終了します。

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

Home PC C# Illustration

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