OpenFileDialogのCustomPlaceとDefaultExt

WPFでファイルを開くダイアログを出す場合は、Microsoft.Win32名前空間にあるOpenFIleDialogクラスを使用します。

OpenFileDialog クラス (Microsoft.Win32)

これはWindows FormsのSystem.Windows.Forms.OpenFileDialogとよく似ているのですが、CustomPlaceというプロパティが追加されており、左メニューの中に一時的なショートカットを置くことができます。Visual Studioでも使われています。

そして、DefaultExtですが、Windows.Formsの時と使い方が違うようで、FilterIndexにFilterプロパティで指定したリストのインデックスを代入しなくてはいけないようです。後に示す例ではUseDefaultExtAsFilterIndexメソッドにてDefaultExtとFilterからFilterIndexを指定しています。
DefaultExtには代入ができるんだけど、ShowDialogすると効いてないようなので困りました。

以下、こんな感じで使っています。

public static class ImageFileDialog
{
    /// <summary>
    /// 画像ファイルを開くダイアログを表示
    /// </summary>
    /// <param name="filePath">得られたファイルパス</param>
    /// <param name="defaultPath">ダイアログを開いた時のパス</param>
    /// <returns>処理の可否</returns>
    public static bool OpenImageDialog(out string filePath, string defaultPath = "")
    {
        // デフォルト値
        filePath = "";

        // ファイルパスを取得
        OpenFileDialog dialog = new OpenFileDialog();
        string[] filters = new string[]
            {
                "Image Files(*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.bmp;*.gif)|*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.bmp;*.gif",
                "All files(*.*)|*.*"
            };
        dialog.Filter = String.Join("|", filters);
        dialog.Title = "Open Image File";
        dialog.DefaultExt = ".png";
        UseDefaultExtAsFilterIndex(dialog, filters);

        // カスタムプレース
        dialog.CustomPlaces = CustomPlace;

        // デフォルトパスを設定
        if(defaultPath != "")
        {
            string getDirectoryName = Path.GetDirectoryName(defaultPath);
            if(Directory.Exists(defaultPath))
                dialog.InitialDirectory = defaultPath;
            else if(Directory.Exists(getDirectoryName))
                dialog.InitialDirectory = getDirectoryName;
        }

        bool? resultDialog = dialog.ShowDialog();
        if(!(resultDialog ?? false))
            return false;

        // ファイルパスを設定
        filePath = dialog.FileName;

        return true;
    }

    private static IList<FileDialogCustomPlace> customPlace = null;

    public static IList<FileDialogCustomPlace> CustomPlace
    {
        get
        {
            if (customPlace == null)
            {
                customPlace = new FileDialogCustomPlace[1]
                {
                    new FileDialogCustomPlace(@"C:\Users\Public\Documents")
                };
            }
            return customPlace;
        }
    }
    
    /// <summary>
    /// ダイアログでデフォルト拡張子を指定する
    /// </summary>
    /// <param name="dialog">ダイアログ</param>
    /// <param name="filters">フィルタ文字列配列</param>
    private static void UseDefaultExtAsFilterIndex(FileDialog dialog, string[] filters)
    {
        string ext = "." + dialog.DefaultExt;
        if (ext == string.Empty)
            return;

        for(int i = 0; i < filters.Length; i++)
        {
            string flt = filters[i];

            string[] lets = flt.Split('|');
            if (lets.Length != 2)
                continue;
            string extsemi = lets[1];

            string[] extarrays = extsemi.Split(';');

            bool existExt = false;
            for (int j = 0; j < extarrays.Length; j++)
            {
                if (extarrays[j].EndsWith(ext))
                {
                    existExt = true;
                    break;
                }
            }

            if (existExt)
            {
                dialog.FilterIndex = i + 1;
                break;
            }
        }
    }
}