もっと詳しく

以前、こちらの記事では、System.Windows.Forms に含まれているファイル選択ダイアログの使用例を紹介しました。

今回は、WindowsApiCodePackというライブラリをインストールすることで利用可能なファイル選択ダイアログについて、ライブラリのインストール方法と使い方について紹介したいと思います。

尚、今回はWPFでの事例を紹介していますが、ライブラリの使い方に関してはWindowsFormとも共通であり、Microsoft Framework 4.7 、 4.8、.NET6 でも利用可能です。

ファイル選択ダイアログの概要

今回紹介するファイル選択ダイアログは、ファイル参照時に用いるダイアログと、ファイル保存時に用いるダイアログの2種類が存在します。

WindowsApiCodePackのインストール方法

インストール方法は、Visual Studioの Nuget でライブラリを選択し、インストールすればOKです。

Nugetの検索欄で ”WindowsAPICodePack”と入力すると、候補の一覧が表示されますので、「Microsoft-WindowsAPICodePack-Shell」を選んで下さい。

WindowsAPICodePack-Shell というよく似た名前のライブラリも表示されますが、この記事で紹介するものとはバージョンや仕様が異なるため、間違って選ばないようにご注意ください。

インストールを開始すると、依存関係のあるMicrosoft-WindowsAPICodePack-Core も一緒に表示されますので、「OK」をクリックして下さい。

ファイル選択ダイアログの使い方

プログラムの冒頭に、 Microsoft.WindowsAPICodePack.Dialogs を参照するたの1行を記述します。

using Microsoft.WindowsAPICodePack.Dialogs;

ファイル選択ダイアログには、参照用と保存用の2種類が用意されているので、それぞれについて説明します。

ファイル参照ダイアログ

ファイル参照ダイアログは、こちらの記事で紹介した CommonOpenFileDialog と同じものを使います。

ダイアログを表示する際は、生成したインスタンスの ShowDialogメソッドを呼び出すだけです。

var dlg = new CommonOpenFileDialog();
dlg.ShowDialog()

ShowDialogメソッドの戻り値が CommonFileDialogResult.Ok であるかを確認し、FileNameプロパティを使って選択されたファイル名を取得します。

if(dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
    var filename = dlg.FileName;
}

尚、複数ファイルを選択したい場合は Multiselect プロパティ に true を設定します。

dlg.Multiselect = true;

尚、Multiselect に true を設定した状態で FileName プロパティを参照すると例外が発生します。

Multiselect を true に設定した時は、必ず FileNames プロパティを使って選択したファイルを取得するようにして下さい。

if(dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
    var filenames = dlg.FileNames;
}

ちなみに、FileNames は IEnumerable<string> 型で複数のファイル名が格納されています。

単純な文字列配列として受け取りたい場合は、 ToArray() メソッドを使って次のように記述して下さい。

var filenames = dlg.FileNames.ToArray();

ファイル保存ダイアログ

ファイル保存ダイアログは CommonSaveFileDialog を使います。

CommonOpenFileDialog と同様、生成したインスタンスの ShowDialogメソッドを呼び出すだけでダイアログが表示できます。

var dlg = new CommonSaveFileDialog();
dlg.ShowDialog()

ShowDialogメソッドの戻り値が CommonFileDialogResult.Ok であることを確認し、FileNameプロパティを参照すれば、選択されたファイル名が取得出来ます。

if(dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
    var filename = dlg.FileName;
}

ダイアログ表示時に、初期値としてファイル名を表示したい場合は、DefaultFileName を使います。

例えば

dlg.DefaultFileName = "abc.def";

と記述すると、ダイアログの「ファイル名」入力欄に、あらかじめ “abc.def” を表示させることが可能です。

フィルターについて

ファイル参照、ファイル保存ともにファイル名のフィルタを設定することが可能です。

フィルターは、CommonFileDialogFilterのインスタンスを生成し、Filters.Add() メソッドを使って登録します。

フィルター条件はいくつも登録することが可能で、更に1つのフィルター条件には “*.csv,*.tsv” のようにカンマ区切りで複数の拡張子を列挙することも可能です。

dlg.Filters.Add(new CommonFileDialogFilter("CSV", "*.csv,*.tsv"));
dlg.Filters.Add(new CommonFileDialogFilter("JPG", "*.jpg"));

主なプロパティ

良く使うプロパティの一覧です。

ファイル選択時とファイル保存時で共通のものも多いですが、一部異なるものもあります。

プロパティ 内容 ファイル参照時 ファイル保存時
Title ダイアログのタイトルを設定 dlg.Title = “フォルダ選択”
InitialDirectory ダイアログ表示時の選択候補となるフォルダ
省略すると直近のフォルダが選択される
dlg.InitialDirectory = @”C:\”
DefaultDirectory 直近に表示したフォルダが見つからない場合の
代替フォルダ
dlg.DefaultDirectory = @”C:\Temp\”;
FileName 選択したファイル名
Filters フィルター dlg.Filters.Add(
new CommonFileDialogFilter(“jpg”, “.jpg“)
)
Multiselect 複数選択の許可 × dlg.Multiselect = true;
FileNames 複数選択時のファイル名一覧 ×
DefaultFileName 初期値として表示したいファイル名 × dlg.DefaultFileName = “abc.def”;

サンプルソース

今回のサンプルプログラムはWPF+C#+.NET6.0 という構成で、WinApiFileDialogSample という名前でプロジェクトを作成しています。

以下は画面(XAML)のソースコードです。

<Window x:Class="WinApiFileDialogSample.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:WinApiFileDialogSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="358" Width="513">
    <Grid>
        <Button x:Name="uxOpenFile" Content="OpenFile" HorizontalAlignment="Center" Margin="0,71,0,0" VerticalAlignment="Top" Height="30" Width="300" Click="uxOpenFile_Click"/>
        <Button x:Name="uxSaveFile" Content="SaveFile" HorizontalAlignment="Center" Margin="0,106,0,0" VerticalAlignment="Top" Height="30" Width="300" Click="uxSaveFile_Click" />
        <TextBox x:Name="uxResult" HorizontalAlignment="Center" Margin="0,146,0,0" VerticalAlignment="Top" Height="25" Width="300"/>
    </Grid>
</Window>

以下は C#のソースコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace WinApiFileDialogSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// ファイルオープンダイアログ
        /// </summary>
        /// <returns></returns>
        public string OpenFileDialog()
        {
            //ダイアログのインスタンス生成
            var dlg = new CommonOpenFileDialog();

            //初期設定
            dlg.Title = "ファイル選択";
            dlg.Filters.Add(new CommonFileDialogFilter("CSV", "*.csv,*.tsv"));
            dlg.Filters.Add(new CommonFileDialogFilter("JPG", "*.jpg"));
            dlg.IsFolderPicker = false;             //ファイル選択ダイアログの場合はfalse
            dlg.InitialDirectory = @"C:\";             //開いておきたいフォルダ
            dlg.DefaultDirectory = @"C:\Users\TEMP";   //直近に使用したフォルダが利用できない時の代替えフォルダ

            //表示
            //ダイアログの表示
            var res = dlg.ShowDialog();

            //戻り値がOKならファイル名を、そうでなければ空文字を返す
            return (res == CommonFileDialogResult.Ok) ? dlg.FileName : "";
        }

        public string SaveFileDialog()
        {
            //ダイアログのインスタンス生成
            var dlg = new CommonSaveFileDialog();
           
            //初期設定
            dlg.Title = "ファイル保存選択";
            dlg.Filters.Add(new CommonFileDialogFilter("CSV", "*.csv,*.tsv"));
            dlg.Filters.Add(new CommonFileDialogFilter("JPG", "*.jpg"));
            dlg.InitialDirectory = @"C:\";             //開いておきたいフォルダ
            dlg.DefaultDirectory = @"C:\Users\TEMP";   //直近に使用したフォルダが利用できない時の代替えフォルダ
            dlg.DefaultFileName = "abc.def";

            //ダイアログの表示
            var res = dlg.ShowDialog();

            //戻り値がOKならファイル名を、そうでなければ空文字を返す
            return (res == CommonFileDialogResult.Ok) ? dlg.FileName : "";
        }

        /// <summary>
        /// OpenFileボタンクリック時のイベントハンドラ
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxOpenFile_Click(object sender, RoutedEventArgs e)
        {
            uxResult.Text = OpenFileDialog();
        }

        /// <summary>
        /// SavaFileボタンクリック時のイベントハンドラ
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxSaveFile_Click(object sender, RoutedEventArgs e)
        {
            uxResult.Text = SaveFileDialog();
        }
    }
}

まとめ

今回は、WindowsApiCodePack というフリーのライブラリのインストール方法、ファイル選択ダイアログ、ファイル保存ダイアログの使い方について解説しました。

System.Window.Forms のダイアログと WindowsApiCodePack のダイアログは、見た目と動作が全く同じですので、どちを使っても問題はありません。

プログラムの作りやすさもさほど変わらないので、好みに合ったものを選んでいただければと思います。

この記事が皆様のお役に立てれば幸いです。