げっそり。CommonOpenFileDialog
を使ったサンプルはそこかしこにありますが、ダイアログから使うとownerがMainWindowになってダイアログの裏に隠れちゃう。ShowDialog
にownerWindowHandle
を渡せば良いんだけど、WPFでどうやるの~ってハマった私の2時間を返して欲しい。
当方のシステムのダイアログは、必ずユニークなタイトルをつける親クラスDialogApplicationBase
を継承していたので、タイトルから探すようにしました。
// すべての画面系の親クラス
// プロパティTitleを持つダイアログ系の親クラスDialogApplicationBaseもこのクラスから派生
public class ApplicationViewModelBase : BindableBase
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// ディレクトリ選択
/// </summary>
/// <param name="dir">選択ディレクトリ</param>
/// <param name="dialogTitle">ダイアログタイトル</param>
/// <param name="initDir">初期選択パス</param>
/// <returns>選択すればtrue</returns>
protected bool IsSelectDirectory(out string dir, string dialogTitle = "なんかいい感じの説明文", string initDir = null)
{
dir = "";
// ダイアログを作成
CommonOpenFileDialog dlg = new CommonOpenFileDialog()
{
IsFolderPicker = true,
Title = dialogTitleKey
};
// 初期パスが指定されていれば反映
if (initDir != null)
{
dlg.InitialDirectory = initDir;
}
// ダイアログからの表示ならダイアログを親に指定
if (this is DialogApplicationBase)
{
if (dlg.ShowDialog(FindWindow(null, (this as DialogApplicationBase).Title)) != CommonFileDialogResult.Ok)
{
return false;
}
}
else
{
if (dlg.ShowDialog() != CommonFileDialogResult.Ok)
{
return false;
}
}
dir = dlg.FileName;
return true;
}
}
実際には、WindowsAPIをまとめたクラスを定義してそこでFindWindow
を宣言したり、
ダイアログのタイトルはリソースキーで管理してたりしますが、ざっくりこんな感じ。
他にもニッチなIT関連要素をまとめていますので、よければ一覧記事もご覧ください。