ダイアログからフォルダ選択ダイアログを開くとモーダルになってない問題[WPF、CommonOpenFileDialog]

げっそり。
CommonOpenFileDialogを使ったサンプルはそこかしこにありますが、ダイアログから使うとownerがMainWindowになってダイアログの裏に隠れちゃう。
ShowDialogownerWindowHandleを渡せば良いんだけど、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関連要素をまとめていますので、よければ一覧記事もご覧ください。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)