Ookii-dialogs-wpf: VistaOpenFileDialog.InitialDirectoryは無視されます

作成日 2019年09月26日  ·  9コメント  ·  ソース: ookii-dialogs/ookii-dialogs-wpf

プロパティInitialDirectoryをローカルおよび既存のフォルダに設定してダイアログを初期化することは無視されます。
ダイアログには、ファイルが開かれた最後のフォルダが常に表示されます。

 VistaOpenFileDialog dialog = new VistaOpenFileDialog();
 dialog.Filter = "JSON Dateien (*.json)|*.json";
 dialog.InitialDirectory = "C:\\";

期待される動作:
InitialDirectoryが「C:\」に設定されている場合、VistaOpenFileDialogは常にC:\のコンテンツを調べます。

Windows 10 Pro 1903 / .Net Framework 4.6

good first issue hacktoberfest help wanted needs-design

最も参考になるコメント

多くのWindowsアプリケーションには、最後のパスを記憶するための「スマート」なデフォルトの動作があるのは事実ですが、アプリの開発者がユーザーを支援するために特定の初期ディレクトリを指定したい場合が多くあります。 私たちのアプリケーションランドスケープでは、ユーザーが特定のプロジェクト関連のディレクトリからロード/保存することを期待しているため、これはデフォルトの動作ですらあります。 ここでは、メモ帳/ペイント/単語の「スマート」な最後のディレクトリを使用するのは面倒で役に立たない。

プラス: Microsoft.Win32.OpenFileDialogはまったく同じプロパティを持ち、期待どおりに使用します。

全てのコメント9件

@soulflymanを報告していただきありがとうございます。 ただし、これは「正しい」動作であると思います。これは、Windowsに付属する他のすべてのアプリで発生する動作と一致するためです。つまり、最後に使用したフォルダーを記憶しています。

メモ帳やペイントでも同じように再現できるはずです。

@buildcompleteはPR#2で同様の問題を報告したので、おそらくこの動作をなんとかしてオーバーライドする方法が必要です(?)、理想的には

それは素晴らしいですね、あなたが言ったように、私は新しい設定で完全に大丈夫でしょう。

デフォルトの動作(メモ帳など)を認識していましたが、InitialDirectoryを手動で設定すると、この動作が変更されると予想しました。
私の想定では、InitialDirectoryは、ダイアログが表示されるたびに、または少なくともアプリケーションのこの実行中のインスタンスで表示されるディレクトリを意味していました。 アプリケーションを閉じて再起動した後でも、無視されるとは思っていませんでした。

同じ問題が発生しています。
さまざまなVistaSaveFileDialogプロパティを設定するさまざまな方法/順序を試しましたが、成功しませんでした。 ダイアログは常にInitialDirectoy設定を無視し、デフォルトを使用します。

'_initialDirectory'がVistaFileDialog.csで目的のパスに設定されていることを確認しました。
そこから、値はNativeMethods.csのCreateItemFromParsingName(string path)に移動し、COMホールから消えます。

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);

  public static Interop.IShellItem CreateItemFromParsingName(string path)
 {
     object item;
     Guid guid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"); // IID_IShellItem
     int hr = NativeMethods.SHCreateItemFromParsingName(path, IntPtr.Zero, ref guid, out item);
     if( hr != 0 )
         throw new System.ComponentModel.Win32Exception(hr);
     return (Interop.IShellItem)item;
 }

このSHCreateItemFromParsingNameメソッドは、返されたCOMオブジェクトがnullのように見えるため、失敗したように見えますか?

CreateItemFromParsingName

SetLastError = trueをメソッドシグネチャに追加し、呼び出し後にMarshal.GetLastWin32Error()を試しましたが、0が返されます。

多くのWindowsアプリケーションには、最後のパスを記憶するための「スマート」なデフォルトの動作があるのは事実ですが、アプリの開発者がユーザーを支援するために特定の初期ディレクトリを指定したい場合が多くあります。 私たちのアプリケーションランドスケープでは、ユーザーが特定のプロジェクト関連のディレクトリからロード/保存することを期待しているため、これはデフォルトの動作ですらあります。 ここでは、メモ帳/ペイント/単語の「スマート」な最後のディレクトリを使用するのは面倒で役に立たない。

プラス: Microsoft.Win32.OpenFileDialogはまったく同じプロパティを持ち、期待どおりに使用します。

私も同じ必要があります。
ダイアログボックスの初期ディレクトリを設定できる設定を追加していただけませんか?
ありがとうございました。

Ookiiライブラリコードに入りました。 次に、 InitialDirectoryプロパティを考慮する方法を見つけました。
このコード行をファイルVistaFileDialog.cs変更する必要があります
メソッドinternal virtual void SetDialogProperties(Ookii.Dialogs.Wpf.Interop.IFileDialog dialog)
このコードを変更する

// Initial directory
if( !string.IsNullOrEmpty(_initialDirectory) )
{
    Ookii.Dialogs.Wpf.Interop.IShellItem item = NativeMethods.CreateItemFromParsingName(_initialDirectory);
    dialog.SetDefaultFolder(item);
}

// Initial directory
if( !string.IsNullOrEmpty(_initialDirectory) )
{
    Ookii.Dialogs.Wpf.Interop.IShellItem item = NativeMethods.CreateItemFromParsingName(_initialDirectory);
    dialog.SetFolder(item);
}

これで完了です。
これで、OokiiダイアログがInitialDirectoryプロパティで開始されます。

それが役立つことを願っています。

@ gitjsdr26あなたは@augustoproieteのためにPRを作成することができます

@nzain 、申し訳ありませんが、GitHubでこれを行う方法がわかりません。

わかりました。この問題に光を当てるために、さらにいくつかの情報を収集しました。

WPFのOpenFileDialog.InitialDirectoryで文書化されているようなInitialDirectoryプロパティについて説明します。 ドキュメントには次のように書かれています。

ファイルダイアログに表示される初期ディレクトリを取得または設定します。

プロパティの名前が同じであるため、OokiiDialogsのユーザーは同じ動作を期待します。 多くの場合、このプロパティを設定するべきではないことに同意します(メモ帳など)が、それは別の話です。 プロパティが設定されている場合は、期待どおりに機能するはずです。

InitialDirectoryは、現在呼び出されているIFileDialog::SetDefaultFolderと混同しないでください。 ここにドキュメントは言います:

最近使用したフォルダー値が使用できない場合に、デフォルトとして使用されるフォルダーを設定します。

これ(最近使用したフォルダがない)が当てはまるかどうかはわかりません。 デフォルトのフォルダを設定しても、私には何の効果もありませんでした。 その機能が誰にでも必要な場合は、 DefaultDirectoryプロパティとして利用できるはずです。 それは昔の時代遅れの遺物かもしれません-これがいつ効果があるか誰かが知っているなら、私に知らせてください。

PR?

#2 PRは2年間オープンしており(!)、同様のことを示唆しています。 作者の@buildcompleteは、彼のシナリオで少なくとも1回は機能していると述べていますが。 彼の修正は古いコードに基づいているようですが、 @ gitjsdr26が示唆しているのと同じことをします:呼び出しを変更します
IFileDialog::SetDefaultFolder(...)からIFileDialog::SetFolder(...)

PRの作成に時間を無駄にしたくありません(私もこの1行を変更します)。

@augustoproieteこれについてどう思うか

このページは役に立ちましたか?
0 / 5 - 0 評価