はじめに
この記事では、Windows Forms で「SaveFileDialog」を使ってファイル保存ダイアログを表示し、ユーザーが指定したパスにデータを書き出す最小構成を解説します。特に ShowDialog()、FileName、Title の3点に絞って、動作の流れと実装のコツを丁寧に説明します。
ポイントは次のとおりです:
・ShowDialog() の戻り値で「保存が確定したか」を判定する。
・Title でダイアログのキャプションをわかりやすくする。
・FileName は「ユーザーが決めた(または既定の)フルパス」であり、実際の保存処理は自分で行う。
説明
SaveFileDialog は、ユーザーに保存先とファイル名を選んでもらうための共通ダイアログです。実体としては「パスを決める UI」を提供するだけで、ファイルの書き込み自体はアプリ側で行います。
Title はダイアログのタイトルバーに表示される文字列です。ここで「何を保存するのか」を端的に示すと、ユーザーが迷いません。
ShowDialog() はダイアログをモーダル表示し、ユーザー操作の結果を DialogResult で返します。保存が確定されたかどうかは DialogResult.OK かで判定します。キャンセル時は保存処理を一切行いません。
FileName は、ユーザーが確定した保存先の「フルパス(例:C:\Users\...\memo.txt)」です。ShowDialog() の結果が OK のときだけ参照するようにします。また、既定のファイル名をあらかじめ提案したい場合は、ダイアログを開く前に FileName に設定しておきます。
サンプルコード
以下は、テキストを入力して「保存…」ボタンで SaveFileDialog を開き、選択されたパスに内容を保存する最小構成の Windows Forms アプリの例です。
private readonly TextBox _txtContent = new TextBox();
private readonly Button _btnSave = new Button();
public MainForm()
{
Text = "SaveFileDialog デモ";
Width = 500;
Height = 360;
// テキスト入力欄
_txtContent.Multiline = true;
_txtContent.ScrollBars = ScrollBars.Both;
_txtContent.Dock = DockStyle.Fill;
// 保存ボタン
_btnSave.Text = "保存...";
_btnSave.AutoSize = true;
_btnSave.Click += OnSaveClick;
// 下部にボタンを右寄せ配置
var bottomPanel = new FlowLayoutPanel
{
Dock = DockStyle.Bottom,
FlowDirection = FlowDirection.RightToLeft,
Height = 52,
Padding = new Padding(8)
};
bottomPanel.Controls.Add(_btnSave);
Controls.Add(_txtContent);
Controls.Add(bottomPanel);
}
private void OnSaveClick(object sender, EventArgs e)
{
// SaveFileDialog は IDisposable。using で確実に破棄します。
using (var sfd = new SaveFileDialog())
{
// Title: ダイアログのキャプションをわかりやすく。
sfd.Title = "メモを保存する場所を選択してください";
// FileName: 既定のファイル名を提案(ユーザーは変更可能)。
sfd.FileName = "memo.txt";
// 必須ではないが、実用上ほぼ必須の設定
sfd.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
sfd.DefaultExt = "txt";
sfd.AddExtension = true; // 拡張子を自動付与
sfd.OverwritePrompt = true; // 上書き時に確認
// ShowDialog(): モーダル表示して結果を受け取る
var result = sfd.ShowDialog(this);
if (result == DialogResult.OK)
{
// FileName: ユーザーが確定したフルパス
var path = sfd.FileName;
// ここで実際の保存処理を行う
File.WriteAllText(path, _txtContent.Text);
MessageBox.Show(
"保存しました:\n" + path,
"保存完了",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
// Cancel の場合は何もしない
}
}
— サンプルコードの解説 —
① ダイアログ生成と破棄: using (var sfd = new SaveFileDialog()) { ... } とすることで、ダイアログ(CommonDialog)のリソースが自動的に解放されます。長時間使い回す必要はありません。
② Title の役割: Title はダイアログのタイトルバーの文言です。「何を保存するのか」を短く明示すると、ユーザーが操作を理解しやすくなります。
③ 既定の FileName: 開く前に FileName に「提案名(例:memo.txt)」を入れておくと、ユーザーはそのまま保存できます。ユーザーが変更すれば、その変更が FileName に反映されます。
④ ShowDialog() と結果判定: ShowDialog() は DialogResult を返します。OK のときだけ FileName を使って保存処理を実行し、Cancel では何もしません。これが最も安全な基本パターンです。
⑤ 実際の保存: SaveFileDialog 自体は保存しません。File.WriteAllText(...) など、アプリ側で明示的に書き込みます。バイナリなら File.WriteAllBytes/ストリームなら FileStream を使います。
⑥ 追加オプション: Filter・DefaultExt・AddExtension・OverwritePrompt などを適切に設定すると、拡張子の付け忘れや上書き事故を防げます(本記事の主題は Title/FileName/ShowDialog() ですが、実用ではほぼ必須)。
つまづきポイント
スペルミスに注意: クラス名は SaveFileDialog です(SaveFileDailog ではありません)。大文字小文字も含めて正確に。
保存は自動で行われない: ShowDialog() で「パスが決まるだけ」です。実際の書き込みは必ず自分で行います。
戻り値チェック忘れ: ShowDialog() の戻り値が DialogResult.OK かどうかを必ず判定。キャンセル時に書き込みを走らせないようにします。
パスの存在・権限: ネットワークドライブや書き込み禁止フォルダでは例外になることがあります。必要に応じて try-catch で保護し、エラーメッセージを表示しましょう。
タイトルとフォームの混同: ダイアログの Title と、フォームのウィンドウタイトル
まとめ
SaveFileDialog は「どこに・何という名前で保存するか」をユーザーに選んでもらうための基本 UI です。Title で目的を明確にし、ShowDialog() の結果を OK で判定、FileName でフルパスを受け取り、アプリ側で確実にファイルを書き出す——この流れを押さえておけば、ほとんどの保存機能は安全かつ直感的に実装できます。


コメント