Ookii-dialogs-wpf: VistaOpenFileDialog.InitialDirectory игнорируется

Созданный на 26 сент. 2019  ·  9Комментарии  ·  Источник: ookii-dialogs/ookii-dialogs-wpf

Инициализация диалогового окна со свойством InitialDirectory, установленным для локальной и существующей папки, игнорируется.
В диалоговом окне всегда отображается последняя папка, в которой был открыт файл.

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

Ожидаемое поведение:
VistaOpenFileDialog всегда показывает содержимое C: \, когда InitialDirectory имеет значение «C: \».

Windows 10 Pro 1903 / .Net Framework 4.6

good first issue hacktoberfest help wanted needs-design

Самый полезный комментарий

Хотя верно, что многие приложения Windows имеют «умное» поведение по умолчанию, чтобы запоминать ваш последний путь, существует много ситуаций, когда разработчик приложения хочет указать конкретный начальный каталог, чтобы помочь пользователю. Для нашего ландшафта приложений это даже поведение по умолчанию, поскольку наши пользователи ожидают загрузки / сохранения в определенные каталоги, связанные с проектом. Использование «умной» последней директории из блокнота / paint / word здесь раздражает и бесполезно.

Плюс: Microsoft.Win32.OpenFileDialog имеет точно такое же свойство и использует его должным образом.

Все 9 Комментарий

Спасибо за сообщение @soulflyman. Однако я считаю, что это «правильное» поведение, поскольку оно соответствует тому, что происходит во всех других приложениях, поставляемых с Windows, т.е. они запоминают последнюю использованную папку.

Вы должны иметь возможность воспроизвести то же самое с помощью Блокнота или Paint.

@buildcomplete сообщил о подобной проблеме с PR # 2, поэтому, возможно, нам нужен способ как-то переопределить это поведение (?), в идеале как параметр согласия, который не вносит критических изменений.

Звучит здорово, я был бы полностью в порядке с новой настройкой, как вы упомянули.

Мне было известно о поведении по умолчанию (например, в блокноте), но я объяснил, что это поведение нужно изменить, когда InitialDirectory устанавливается вручную.
Я предполагал, что InitialDirectory должен быть каталогом, который отображается каждый раз при отображении диалогового окна или, по крайней мере, в этом запущенном экземпляре приложения. Я не ожидал, что меня проигнорируют даже после закрытия и перезапуска приложения.

У меня такая же проблема.
Экспериментировал с разными способами / порядком установки различных свойств VistaSaveFileDialog, но безуспешно. Диалог всегда игнорирует настройку InitialDirectoy и использует значение по умолчанию.

Я подтвердил, что _initialDirectory устанавливается на желаемый путь в VistaFileDialog.cs.
Оттуда значение попадает в CreateItemFromParsingName(string path) в NativeMethods.cs, а затем исчезает в дыре 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-объект кажется нулевым?

CreateItemFromParsingName

Я добавил SetLastError = true в подпись метода и попробовал Marshal.GetLastWin32Error() после вызова, но он вернул 0.

Хотя верно, что многие приложения Windows имеют «умное» поведение по умолчанию, чтобы запоминать ваш последний путь, существует много ситуаций, когда разработчик приложения хочет указать конкретный начальный каталог, чтобы помочь пользователю. Для нашего ландшафта приложений это даже поведение по умолчанию, поскольку наши пользователи ожидают загрузки / сохранения в определенные каталоги, связанные с проектом. Использование «умной» последней директории из блокнота / paint / word здесь раздражает и бесполезно.

Плюс: 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

@nzain , извините, я не знаю, как это сделать с GitHub.

Хорошо, я собрал дополнительную информацию, чтобы пролить свет на эту проблему.

Мы говорим о свойстве InitialDirectory аналогичном описанному для WPF OpenFileDialog.InitialDirectory . В документации говорится:

Получает или задает начальный каталог, отображаемый в файловом диалоговом окне.

Пользователи диалогов Ookii ожидают такого же поведения, потому что свойство имеет то же имя. Я согласен, во многих ситуациях это свойство не следует устанавливать (блокнот и т. Д.), Но это отдельная история. _Если_ свойство установлено, оно должно работать должным образом.

InitialDirectory не следует путать с IFileDialog::SetDefaultFolder который сейчас вызывается. Здесь в документации говорится:

Устанавливает папку, используемую по умолчанию, если нет доступного значения недавно использованной папки.

Я не уверен, что это (нет доступной недавно использованной папки) когда-либо. Установка папки по умолчанию на меня никогда не влияла. Если эта функция необходима кому-либо, она должна быть доступна как свойство DefaultDirectory . Это может быть устаревший артефакт старых времен - если кто-нибудь знает, когда это подействует, дайте мне знать.

PR?

PR №2 открыт уже два года (!) И предполагает то же самое. Хотя автор @buildcomplete упоминает, что он работает хотя бы один раз в его сценарии. Его исправление, похоже, основано на старом коде, но делает то же самое, что предлагает @ gitjsdr26 : изменить вызов
IFileDialog::SetDefaultFolder(...) на IFileDialog::SetFolder(...) .

Не хочу тратить время на создание PR (я бы тоже эту строчку поменял).

@augustoproiete, дайте нам знать, что вы думаете об этом :)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги