ファイル操作系ダイアログで、
初回に開くフォルダーや、開いたファイル/フォルダーを保持したい場合ってありますよね。
今日はその保持方法について。
標準のOpenFileDialog、SaveFileDialogはデフォルトで、
前回選択したファイルのパスが次回表示されます。
アプリケーション単位に保持しており、
アプリケーションを再度起動しても保持しているので、レジストリに持っているのでしょう。
なぜかFolderBrowserDialogに関しては保持されていませんが。(2018/10月執筆時点)
ググった感じだと、
レジストリの↓の階層に保存されているらしい。
HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/LastVisitedPidMRU
格納フォルダーの名前は、確かにそれっぽいのですが、
バイナリが格納してあるだけで、実際の格納値の規則などはわかりませんorz
レジストリの値を見るのは現実的ではないので、
自作してみようと思います。
標準と同じ挙動では意味がないので、
下記の要件で実装したいと思います。
実装のイメージ↓
以下サンプルソースです。
Form1と拡張メソッドクラスの2つ用意します。
Form1.cs
using System;
using System.Windows.Forms;
namespace FileOperatorSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.ShowDialogEx(this);
}
private void button2_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.ShowDialogEx(this);
}
private void button3_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.ShowDialogEx(this);
}
}
}
デザインはこんな感じ↓
拡張メソッドクラス
using System;
using System.IO;
using System.Windows.Forms;
namespace FileOperatorSample
{
/// <summary>
/// ファイル操作系のダイアログの拡張メソッド定義クラス
/// </summary>
public static class FileDialogExtentions
{
/// <summary>環境変数名</summary>
private static string environmentVariableName = $"{Application.ProductName}_CURRENT_DIR_PATH";
/// <summary>環境変数アクセサ</summary>
private static string EnvironmentValue
{
get
{
// 環境変数の値取得
string variable = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.User);
if (string.IsNullOrEmpty(variable))
{ // Nullの場合(初回)のみデスクトップとする
return Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
}
return variable;
}
set
{
// 環境変数の値設定
Environment.SetEnvironmentVariable(environmentVariableName, value, EnvironmentVariableTarget.User);
}
}
/// <summary>
/// <para>OpenFileDialog.ShowDialogの拡張メソッド</para>
/// <para>初期フォルダーを設定し、OK選択時に作業ディレクトリを保存します</para>
/// </summary>
/// <param name="self"></param>
/// <param name="window"></param>
/// <returns></returns>
public static DialogResult ShowDialogEx(this OpenFileDialog self, IWin32Window window)
{
self.InitialDirectory = EnvironmentValue;
DialogResult ret = self.ShowDialog(window);
if (ret.Equals(DialogResult.OK))
{ // OK選択時は選択したファイルのディレクトリを保存する
EnvironmentValue = Path.GetDirectoryName(self.FileName);
}
return ret;
}
/// <summary>
/// <para>FolderBrowserDialog.ShowDialogの拡張メソッド</para>
/// <para>初期フォルダーを設定し、OK選択時に作業ディレクトリを保存します</para>
/// </summary>
/// <param name="self"></param>
/// <param name="window"></param>
/// <returns></returns>
public static DialogResult ShowDialogEx(this FolderBrowserDialog self, IWin32Window window)
{
self.SelectedPath = EnvironmentValue;
DialogResult ret = self.ShowDialog(window);
if (ret.Equals(DialogResult.OK))
{ // OK選択時は選択したディレクトリを保存する
EnvironmentValue = self.SelectedPath;
}
return ret;
}
/// <summary>
/// <para>SaveFileDialog.ShowDialogの拡張メソッド</para>
/// <para>初期フォルダーを設定し、保存選択時に作業ディレクトリを保存します</para>
/// </summary>
/// <param name="self"></param>
/// <param name="window"></param>
/// <returns></returns>
public static DialogResult ShowDialogEx(this SaveFileDialog self, IWin32Window window)
{
self.InitialDirectory = EnvironmentValue;
DialogResult ret = self.ShowDialog(window);
if (ret.Equals(DialogResult.OK))
{ // OK選択時は選択したファイルのディレクトリを保存する
EnvironmentValue = Path.GetDirectoryName(self.FileName);
}
return ret;
}
}
}
順に実行していきます。
初回起動時
デスクトップになっていますね。
ここで任意のファイルを選択してみます。
そうすると↓の通り環境変数に表示されます。
それでは2回目
無事選択したファイルのフォルダーが、初期表示されました。
参考までに、アプリケーションを起動するたびに、
保持しているパスをリセットしたい場合は、
環境変数アクセサの箇所を
EnvironmentVariableTarget.User
↓
EnvironmentVariableTarget.Process
のように変更すればいけます。
上の変更は、環境変数の持ち方を現在のユーザ ⇒ プロセスに限定しています。
おしまい。