Ookii-dialogs-wpf: VistaOpenFileDialog.InitialDirectory wird ignoriert

Erstellt am 26. Sept. 2019  ·  9Kommentare  ·  Quelle: ookii-dialogs/ookii-dialogs-wpf

Das Initialisieren eines Dialogfelds mit der Eigenschaft InitialDirectory, die auf einen lokalen und vorhandenen Ordner festgelegt ist, wird ignoriert.
Der Dialog zeigt immer den letzten Ordner an, in dem eine Datei geöffnet wurde.

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

Erwartetes Verhalten:
Der VistaOpenFileDialog zeigt immer den Inhalt von C: \ an, wenn InitialDirectory auf "C: \" gesetzt ist.

Windows 10 Pro 1903 / .Net Framework 4.6

good first issue hacktoberfest help wanted needs-design

Hilfreichster Kommentar

Zwar haben viele Windows-Anwendungen ein "intelligentes" Standardverhalten, um sich an Ihren letzten Pfad zu erinnern, aber es gibt viele Situationen, in denen der Entwickler einer App ein bestimmtes Anfangsverzeichnis angeben möchte, um dem Benutzer zu helfen. Für unsere Anwendungslandschaft ist dies sogar das Standardverhalten, da unsere Benutzer erwarten, dass sie aus bestimmten projektbezogenen Verzeichnissen geladen / in diese gespeichert werden. Die Verwendung des "intelligenten" letzten Verzeichnisses von Notepad / Paint / Word ist hier ärgerlich und nutzlos.

Plus: Das Microsoft.Win32.OpenFileDialog hat genau die gleiche Eigenschaft und verwendet sie wie erwartet.

Alle 9 Kommentare

Vielen Dank für die Meldung von @soulflyman. Ich glaube jedoch, dass dies das "richtige" Verhalten ist, da es mit dem übereinstimmt, was in allen anderen mit Windows gelieferten Apps passiert - dh sie erinnern sich an den zuletzt verwendeten Ordner.

Sie sollten in der Lage sein, dasselbe mit Notepad oder Paint zu reproduzieren.

@buildcomplete hat ein ähnliches Problem mit PR # 2 gemeldet. Vielleicht brauchen wir eine Möglichkeit, dieses Verhalten irgendwie (?) zu überschreiben, idealerweise als Opt-In-Einstellung, die keine bahnbrechende Änderung einführt.

Das hört sich toll an, ich würde mit einem neuen Settign, wie Sie erwähnt haben, völlig in Ordnung sein.

Ich war mir des Standardverhaltens (wie Notepad) bewusst, aber ich habe erwartet, dass sich dieses Verhalten ändert, wenn InitialDirectory manuell eingestellt wird.
Ich ging davon aus, dass InitialDirectory das Verzeichnis sein soll, das jedes Mal angezeigt wird, wenn der Dialog angezeigt wird, oder zumindest in dieser laufenden Instanz der Anwendung. Ich hatte nicht erwartet, auch nach dem Schließen und Neustarten der Anwendung ignoriert zu werden.

Ich habe das gleiche Problem.
Experimentiert mit verschiedenen Methoden / Reihenfolge zum Festlegen der verschiedenen VistaSaveFileDialog-Eigenschaften ohne Erfolg. Der Dialog ignoriert immer die InitialDirectoy-Einstellung und verwendet die Standardeinstellung.

Ich habe bestätigt, dass '_initialDirectory' in VistaFileDialog.cs auf meinen gewünschten Pfad gesetzt wird.
Von dort gelangt der Wert in NativeMethods.cs zu CreateItemFromParsingName(string path) und verschwindet dann im COM-Loch.

[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;
 }

Diese SHCreateItemFromParsingName -Methode scheint fehlzuschlagen, da das zurückgegebene COM-Objekt null zu sein scheint?

CreateItemFromParsingName

Ich habe SetLastError = true zur Methodensignatur hinzugefügt und nach dem Aufruf Marshal.GetLastWin32Error() ausprobiert, aber es wird 0 zurückgegeben.

Zwar haben viele Windows-Anwendungen ein "intelligentes" Standardverhalten, um sich an Ihren letzten Pfad zu erinnern, aber es gibt viele Situationen, in denen der Entwickler einer App ein bestimmtes Anfangsverzeichnis angeben möchte, um dem Benutzer zu helfen. Für unsere Anwendungslandschaft ist dies sogar das Standardverhalten, da unsere Benutzer erwarten, dass sie aus bestimmten projektbezogenen Verzeichnissen geladen / in diese gespeichert werden. Die Verwendung des "intelligenten" letzten Verzeichnisses von Notepad / Paint / Word ist hier ärgerlich und nutzlos.

Plus: Das Microsoft.Win32.OpenFileDialog hat genau die gleiche Eigenschaft und verwendet sie wie erwartet.

Ich habe das gleiche Bedürfnis.
Könnten Sie bitte eine Einstellung hinzufügen, mit der Sie das Anfangsverzeichnis des Dialogfelds festlegen können?
Vielen Dank.

Ich ging in den Ookii-Bibliothekscode. dann fand ich heraus, wie man die InitialDirectory -Eigenschaft berücksichtigt.
Sie müssen diese Codezeile in die Datei VistaFileDialog.cs ändern
In Methode internal virtual void SetDialogProperties(Ookii.Dialogs.Wpf.Interop.IFileDialog dialog)
Ändern Sie diesen Code

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

zu

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

Das ist erledigt.
Jetzt beginnt der Ookii-Dialog mit der Eigenschaft InitialDirectory .

Hoffe es könnte helfen.

@ gitjsdr26 Sie könnten eine PR für @augustoproiete erstellen

@nzain , sorry, ich weiß nicht, wie ich das mit GitHub machen soll.

Ok, ich habe weitere Informationen gesammelt, um Licht in dieses Problem zu bringen.

Wir sprechen über eine InitialDirectory -Eigenschaft, wie sie für das dokumentiert ist . Die Dokumentation sagt:

Ruft das Anfangsverzeichnis ab, das von einem Dateidialog angezeigt wird, oder legt dieses fest.

Benutzer von Ookii-Dialogen erwarten dasselbe Verhalten, da die Eigenschaft denselben Namen hat. Ich stimme zu, in vielen Situationen sollte diese Eigenschaft nicht festgelegt werden (Notizblock usw.), aber das ist eine andere Geschichte. _Wenn_ die Eigenschaft festgelegt ist, sollte sie wie erwartet funktionieren.

Das InitialDirectory ist nicht mit IFileDialog::SetDefaultFolder zu verwechseln, das derzeit aufgerufen wird. Hier steht in der Dokumentation:

Legt den standardmäßig verwendeten Ordner fest, wenn kein kürzlich verwendeter Ordnerwert verfügbar ist.

Ich bin mir nicht sicher, ob dies jemals der Fall ist (kein kürzlich verwendeter Ordner verfügbar). Das Festlegen des Standardordners hatte für mich nie Auswirkungen. Wenn diese Funktionalität für jemanden erforderlich ist, sollte sie als DefaultDirectory -Eigenschaft verfügbar sein. Es könnte ein veraltetes Artefakt alter Zeiten sein - wenn jemand weiß, wann dies Auswirkungen hat, lassen Sie es mich bitte wissen.

PR?

Die PR Nr. 2 ist seit zwei Jahren (!) Offen und schlägt etwas Ähnliches vor. Obwohl der Autor @buildcomplete erwähnt, dass es in seinem Szenario mindestens einmal funktioniert. Sein Fix scheint auf altem Code zu basieren, macht aber dasselbe wie @ gitjsdr26 vorschlägt: Ändern Sie den Aufruf
IFileDialog::SetDefaultFolder(...) bis IFileDialog::SetFolder(...) .

Ich möchte keine Zeit mit der PR-Erstellung verschwenden (ich würde auch diese einzelne Zeile ändern).

@augustoproiete bitte Ihre Meinung dazu mit :)

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen