none
フォルダ選択ダイアログで選択されていない事の判別 RRS feed

  • 質問

  • Windows API Code PackのCommonOpenFileDialogを下記イメージで使用しています。

    var commonOpenFileDialog = new CommonOpenFileDialog
    {
        Title = Properties.Resources.SelectJobIDDialogTitle,
        IsFolderPicker = true,
        Multiselect = true,
        ShowPlacesList = false
    };

    if (commonOpenFileDialog.ShowDialog() == CommonFileDialogResult.Ok)
    {
        List<string> selectedFolders = commonOpenFileDialog.FileNames.ToList();
    }

    現状、当ダイアログ上でフォルダをひとつも選択せずに「フォルダの選択」ボタンを押すと、
    必ずselectedFolders変数に下記が設定されます。
    1)ダイアログ表示後、何もせず「フォルダの選択」ボタンを押した時
     ダイアログ表示時のカレントフォルダパス
    2)ダイアログ表示後、上部のフォルダ切り替え操作後、フォルダ選択せず「フォルダの選択」ボタンを押した時
     フォルダ切り替え後のフォルダパス
     ※フォルダ切り替え後、下部のテキストボックス内を手動クリアしても同様の動作

    やりたいことはフォルダ選択無しの場合、
    メッセージボックスで「フォルダが選択されていません」と出力したいだけです。
    selectedFolders変数に何も設定されない事で判断できると思っていたのですが、
    普通ではない仕様みたいです。

    フォルダ複数選択が可能ならば、CommonOpenFileDialog以外の方策でもかまいません。
    なるべく自作、カスタマイズなしの案を教えてください。
    よろしくお願いします。


    2019年12月3日 5:46

すべての返信

  • 右ペインで何も選択されていない場合、左ペインで現在アクティブな階層が選択されているものと見做されます。

    左ペインが未選択の状態にはならないので、下記で代用できないでしょうか。

    AllowNonFileSystemItems = false,
    InitialDirectoryShellContainer = (ShellContainer)KnownFolders.Computer,

    2019年12月3日 6:12
  • 早速のご回答ありがとうございます。
    おっしゃるとおり、左ペインのアクティブが即ち選択状態であると捉えると
    「非選択状態とはなんぞや」ということにもなりそうで、あながちおかしな仕様ではないとも思えてきました。
    ですが、ShowPlacesList = falseにて左ペインを非表示にしている場合は
    操作している人間からすると右ペインしか見えず、
    右ペイン内のフォルダ非選択なのにその上のフォルダ(左ペインアクティブ)が取得されてしまうという捉え方をされそうです。

    さて、ご提案の修正を入れてみたのですが、これは
    選択不能にしたはずのKnownFolders.ComputerがselectedFolders変数(あるいは別プロパティ?)に
    設定されていたなら、即ち非選択を意味するという事を意図したものでしょうか?
    初期表示がKnownFolders.Computer位置になるだけで、
    非選択状態を何らかの差異で見出すことができませんでした。
    再度、この意図を教えていただきたいです。

    どうにもならない場合は、ShowPlacesList = trueにして、
    (右ペインが非選択でも)左ペインが選択されている事を明確にし、この仕様で説得することにするつもりです。

    2019年12月3日 7:38
  • 初期選択のアイテムを、非ファイルシステムである「PC」にしていますので、「どこかを選択しない限り、CommonFileDialogResult.Ok にはならない」という状態を意図した物です。

    左ペイン(TreeView)と右ペイン(ListView)の仕様については先に述べた通りであり、それは OS の既定の動作なので手を加えるべきではないでしょう。とはいえ、AllowNonFileSystemItems = false である以上、『フォルダが選択されていません』の代わりに『このプログラムを使用してこの場所を開けません。別の場所を試してください。』が表示されますので、「選択状態を何も変えずに、そのまま確定しようとする」ことを阻害する一助にはなるはずです(もしも初期フォルダーを明示的に指定していなかった場合、二回目以降の起動時に、前回選択した場所が開かれることになります)。

    どうしても左ペインは気にせず、右ペインを基準に追跡したいのであれば、上記に加えて、さらにダイアログが閉じられた後で追加判定を行ってみるのは如何でしょう。たとえば下記のいずれかを満たす場合には、左ペインからの選択であったと見做せるかもしれません。

    ①選択された FileNames が 1 件で、それが最後に発生した FolderChanging イベントの e.Folder と一致している場合
    ②SelectionChanged イベントが一度も呼ばれなかった場合
    ③FolderChanged イベントの発生後、一度もSelectionChanged イベントが呼ばれなかった場合

    2019年12月3日 8:09
  • ShowPlacesList = falseにて左ペインを非表示にしている場合は

    そもそも ShowPlaceList (内部的には FOS_HIDEPINNEDPLACES フラグだと思います) は、左ペインの表示/非表示を切り替えるための物では無いのでは?

    少なくとも 手元の環境 (Win10 v1909) では、ShowPlaceList の設定と左ペインの表示/非表示は連動していないようで、左ペインのOn/Off は、ダイアログ のメニューから [整理]-[レイアウト]-[ナビゲーション ウィンドウ] から行われるようになっています。

    2019年12月3日 8:30
  • 再度の回答ありがとうございます。
    当方、Win7(v6.1)にて実施していましたが、
    Win10で表示させてみると、ShowPlaceListが左ペインとは連動していない事がわかりました。
    おっしゃるとおりで、メニューで表示/非表示切り替えでした。
    Win7では、ShowPlaceList=falseにすると、初期表示時に左ペイン内容が非表示になりますが、
    メニューにより再表示されるので、この件に関してのこのプロパティは全く無意味なことがわかりました。
    ありがとうございます。
    2019年12月5日 4:14
  • 再度の回答ありがとうございます。
    ・初期表示位置を限定させたくない。(前回開いた位置をデフォルトとしたい)
    ・基本的にはダイアログ下部のテキストボックスに設定されるフォルダを選択されたものとしたい。
     ※つきつめると、これがうまく動作していない事が本ダイアログの一番の欠陥だと思います。

    イベント処理のアイデアありがとうございます。
    <ダイアログのイベント仕様>
    1)初回表示時
     DialogOpening
     SelectionChangedイベントが発生する。
     ※左ペインフォルダがデフォルト選択されるため、
      SelectionChangedイベントが発生するもののテキストボックスが空である。
    2)右ペインでフォルダ選択時(フォルダの中に入る動作ではなく)
     SelectionChangedイベントのみが発生する。
    3)それ以外の操作時(フォルダ移動を伴う)
     FolderChanging
     FolderChanged
     SelectionChangedイベントが発生する。
    4)テキストボックス入力(クリア含む)
     アプリ側で取得可能なイベントは発生しない。

    上記の仕様の様なので、
    ダイアログ初期表示時(テキストボックスが空状態時)に
    そのまま「フォルダ選択」ボタンを押下された場合は、
    SelectionChangedイベントハンドラ内にてフラグ(初回、それ以外)を設ける事により、
    非選択である旨のメッセージ表示をする様に実装しました。
    これ以降、意図的にテキストボックスクリア後に、
    「フォルダ選択」ボタンを押下された場合は為す術なく
    (その時選択されていたフォルダが選択データとして取得される)、
    ”選択を取りやめる意思であるならば、「キャンセル」ボタンを押下してください”という仕様にします。

    完璧とはなりませんでしたが、
    イベント処理のヒントを与えて頂きありがとうございました。
    2019年12月5日 4:18
  • savicevicさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    >>初期表示がKnownFolders.Computer位置になるだけで、
    非選択状態を何らかの差異で見出すことができませんでした。
    再度、この意図を教えていただきたいです。
    どうにもならない場合は、ShowPlacesList = trueにして、
    (右ペインが非選択でも)左ペインが選択されている事を明確にし、この仕様で説得することにするつもりです。

    →「左ペイン(TreeView)および右ペイン(ListView)の仕様は上記のとおりであり、OSのデフォルトの動作であるため変更しないでください。」 
    したがって、多くの特別な要件がある場合は、必要に応じてカスタムダイアログを作成します。

    これら2つのオープンソースプロジェクトをご参照いただければと思います。
    WPF Folder Browser
    OpenFileOrFolderDialog

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2019年12月6日 7:45
    モデレータ