[C#][Windows Formsアプリ][SaveFileDialog] CheckPathExists/CheckFileExists/CreatePrompt を使いこなす

スポンサーリンク

はじめに

今回は Windows Forms の SaveFileDialog における「パス・ファイルの存在チェック」と「新規作成の促し」に関わる3つのプロパティ、CheckPathExistsCheckFileExistsCreatePrompt をまとめて解説します。ユーザーが存在しないフォルダやファイル名を入力したときにどう振る舞うかは、保存体験の安心感を左右します。本記事では既定値と役割、相互作用(どれがいつ効くか)、実装の勘所を、動くサンプルとともに丁寧に説明します。

この記事で学べること:
CheckPathExistsCheckFileExistsCreatePrompt の役割と既定値
・「存在しないフォルダ/ファイル」を指定したときの挙動とユーザーへのガイダンス
・現実的なおすすめ設定と、例外安全な保存パターン

説明

CheckPathExists(既定:true
ユーザーが指定した保存先パスの「フォルダ」が存在しない場合に、ダイアログ内で警告します。たとえば C:\NoSuchFolder\memo.txt のように存在しないフォルダを打ち込んだとき、誤保存を未然に防げます。通常は true のままでOKです。

CheckFileExists(既定:false
指定した「ファイル」が存在しない場合に警告します。SaveFileDialog は新規ファイルの作成が主目的のため、多くのケースでは false(既定)のままにします。もし true にすると「既存のファイルしか選べない」挙動になるため、上書き前提のツール等、特殊な要件でのみ使います。

CreatePrompt(既定:false
ファイルが存在しないときに「新しく作成しますか?」という確認をダイアログ側で出すかを制御します。CheckFileExists = false のときにのみ意味があります(true だと「存在しないからダメ」という話になるため)。ユーザーの安心感を高めたいなら true にするのも手です。

相互作用の目安
・存在しないフォルダCheckPathExists が警告(推奨:true)。
・存在しないファイルCheckFileExists = true ならNG、false なら CreatePrompt = true のとき「作る?」確認。
・既存ファイルへの上書き確認は別物(OverwritePrompt)。今回は主役ではありませんが、併用時の二重確認に注意。

サンプルコード

テキストを入力して「保存…」を押すだけの最小アプリです。チェックボックスで3つのプロパティを切り替え、挙動の違いを体感できます。

using System; using System.IO; 
using System.Text; 
using System.Windows.Forms;

public class MainForm : Form
{
private readonly TextBox _txt = new TextBox();
private readonly CheckBox _chkPathExists = new CheckBox();
private readonly CheckBox _chkFileExists = new CheckBox();
private readonly CheckBox _chkCreatePrompt = new CheckBox();
private readonly Button _btnSave = new Button();

public MainForm()
{
    Text = "SaveFileDialog: CheckPathExists / CheckFileExists / CreatePrompt";
    Width = 680;
    Height = 420;

    _txt.Multiline = true;
    _txt.ScrollBars = ScrollBars.Both;
    _txt.Dock = DockStyle.Fill;

    _chkPathExists.Text = "CheckPathExists(フォルダ存在を確認)";
    _chkPathExists.Checked = true;    // 既定:true
    _chkPathExists.AutoSize = true;

    _chkFileExists.Text = "CheckFileExists(ファイル存在を確認)";
    _chkFileExists.Checked = false;   // 既定:false
    _chkFileExists.AutoSize = true;

    _chkCreatePrompt.Text = "CreatePrompt(新規作成の確認を出す)";
    _chkCreatePrompt.Checked = true;  // 推奨例:true(既定は false)
    _chkCreatePrompt.AutoSize = true;

    _btnSave.Text = "保存...";
    _btnSave.AutoSize = true;
    _btnSave.Click += OnSaveClick;

    var top = new FlowLayoutPanel
    {
        Dock = DockStyle.Top,
        Height = 72,
        Padding = new Padding(8),
        FlowDirection = FlowDirection.LeftToRight,
        WrapContents = false
    };
    top.Controls.Add(_chkPathExists);
    top.Controls.Add(_chkFileExists);
    top.Controls.Add(_chkCreatePrompt);
    top.Controls.Add(_btnSave);

    Controls.Add(_txt);
    Controls.Add(top);
}

private void OnSaveClick(object? sender, EventArgs e)
{
    using (var sfd = new SaveFileDialog())
    {
        // 今回の主役たち
        sfd.CheckPathExists = _chkPathExists.Checked;
        sfd.CheckFileExists = _chkFileExists.Checked;
        sfd.CreatePrompt    = _chkCreatePrompt.Checked;

        // 付随:上書き確認は OS に任せる(既定 true)
        sfd.OverwritePrompt = true;

        // 使い勝手のための最低限設定
        sfd.Title = "ファイルを保存";
        sfd.FileName = "memo.txt"; // 提案名
        sfd.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
        sfd.DefaultExt = "txt";
        sfd.AddExtension = true;
        sfd.RestoreDirectory = true;

        var dr = sfd.ShowDialog(this);
        if (dr == DialogResult.OK)
        {
            var path = sfd.FileName;

            try
            {
                // 実際の保存(UTF-8 BOMなし)
                File.WriteAllText(path, _txt.Text, new UTF8Encoding(false));

                MessageBox.Show(
                    "保存しました:\n" + path,
                    "保存完了",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    "保存に失敗しました。\n" + ex.Message,
                    "エラー",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
    }
}


}
実行例

実行例

— サンプルコードの解説 —

① CheckPathExists: 存在しないフォルダへ保存しようとすると、ダイアログ内で警告されます。アプリ側で特別なコードを書かなくても、ユーザーに正しい場所を促せます。

② CheckFileExists: true にすると、新規ファイル名を入力してもエラーになりやすく、保存できません。保存=新規作成が主目的の画面では通常 false のままにします。

③ CreatePrompt: ファイルが存在しない場合、ダイアログが「作成しますか?」と尋ねます(CheckFileExists = false のときに有効)。ユーザーの不安を減らしたいときに有効です。

④ 例外対策: ダイアログがOKでも、書き込みは権限・ディスク・ネットワークの事情で失敗し得ます。try-catch でユーザーに正直に伝えるのが実践的です。

⑤ OverwritePrompt: 既存ファイルに上書きする際の確認は OverwritePrompt(既定で true)。CreatePrompt と対象が違うため、両方を true にしても「二重に出る」ことはありません(片方は“存在しないファイル”、もう片方は“既存ファイル”)。

つまづきポイント

「新規作成できない」原因の取り違え: CheckFileExists = true だと「存在しないファイル名」をはねます。保存できないときはまずこの設定を疑いましょう。

存在しないフォルダ + CheckPathExists = false: ダイアログは素通りし、File.WriteAllTextDirectoryNotFoundException が発生します。通常は true を推奨。

CreatePrompt の勘所: CreatePrompt は「新規ファイル」のときだけ。既存ファイルには出ません(その場合は OverwritePrompt の出番)。

OS バージョン差やUIスタイル: 警告の文言やUIの見た目はOSにより異なります。ロジックはアプリ側で堅牢に(例外処理・パス検証)。

ネットワークやリダイレクト環境: UNC/OneDrive/リダイレクトされたドキュメント等ではタイムアウトやアクセス拒否が起こりやすいです。保存後のメッセージにパスを明示し、ユーザーが場所を確認できるようにしましょう。

まとめ

CheckPathExists はフォルダ、CheckFileExists はファイルの存在チェック、CreatePrompt は「無いなら作る?」の確認を担います。現実的には、CheckPathExists = trueCheckFileExists = falseCreatePrompt = (好みで)true が扱いやすい型。あとは例外処理と上書き確認(OverwritePrompt)を添えれば、安心して使える保存ダイアログになります。

Please follow and like us:

コメント

タイトルとURLをコピーしました