Ookii-dialogs-wpf: VistaOpenFileDialog.InitialDirectory é ignorado

Criado em 26 set. 2019  ·  9Comentários  ·  Fonte: ookii-dialogs/ookii-dialogs-wpf

A inicialização de uma caixa de diálogo com a propriedade InitialDirectory definida como uma pasta local e existente é ignorada.
A caixa de diálogo sempre mostra a última pasta onde um arquivo foi aberto.

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

Comportamento esperado:
O VistaOpenFileDialog sempre mostra o conteúdo de C: \ quando InitialDirectory é definido como "C: \".

Windows 10 Pro 1903 / .Net Framework 4.6

good first issue hacktoberfest help wanted needs-design

Comentários muito úteis

Embora seja verdade que muitos aplicativos do Windows têm um comportamento padrão "inteligente" para lembrar seu último caminho, há muitas situações em que o desenvolvedor de um aplicativo deseja especificar um diretório inicial específico para ajudar o usuário. Para o nosso cenário de aplicativos, este é até o comportamento padrão, já que nossos usuários esperam carregar / salvar em diretórios específicos relacionados ao projeto. Usar o último diretório "inteligente" do notepad / paint / word é irritante e inútil aqui.

Mais: Microsoft.Win32.OpenFileDialog tem exatamente a mesma propriedade e a usa como esperado.

Todos 9 comentários

Obrigado por relatar @soulflyman. No entanto, acredito que este seja o comportamento "correto", pois corresponde ao que acontece em todos os outros aplicativos que vêm com o Windows - ou seja, eles se lembram da última pasta usada.

Você deve ser capaz de reproduzir o mesmo com o bloco de notas ou o Paint.

@buildcomplete relatou um problema semelhante com PR # 2, então talvez precisemos de uma maneira de substituir esse comportamento de alguma forma (?), idealmente como uma configuração opcional que não introduz uma alteração significativa.

Isso parece ótimo, eu estaria totalmente bem com um novo conjunto de configurações, como você mencionou.

Eu estava ciente do comportamento padrão (como o bloco de notas), mas eu esperava que esse comportamento mudasse quando InitialDirectory for definido manualmente.
Minha suposição era que InitialDirectory deveria ser o diretório que é exibido sempre que a caixa de diálogo é mostrada ou pelo menos nesta instância em execução do aplicativo. Não esperava ser ignorado mesmo depois de fechar e reiniciar o aplicativo.

Eu estou experimentando o mesmo problema.
Experimentou diferentes maneiras / ordem de definir as várias propriedades do VistaSaveFileDialog sem sucesso. A caixa de diálogo sempre ignora a configuração InitialDirectoy e usa o padrão.

Eu confirmei que '_initialDirectory' foi definido como meu caminho desejado em VistaFileDialog.cs.
A partir daí, o valor segue para CreateItemFromParsingName(string path) em NativeMethods.cs e, em seguida, desaparece no buraco 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;
 }

Este método SHCreateItemFromParsingName parece falhar, pois o objeto COM retornado parece ser nulo?

CreateItemFromParsingName

Eu adicionei SetLastError = true à assinatura do método e tentei Marshal.GetLastWin32Error() após a chamada, mas ele retorna 0.

Embora seja verdade que muitos aplicativos do Windows têm um comportamento padrão "inteligente" para lembrar seu último caminho, há muitas situações em que o desenvolvedor de um aplicativo deseja especificar um diretório inicial específico para ajudar o usuário. Para o nosso cenário de aplicativos, este é até o comportamento padrão, já que nossos usuários esperam carregar / salvar em diretórios específicos relacionados ao projeto. Usar o último diretório "inteligente" do notepad / paint / word é irritante e inútil aqui.

Mais: Microsoft.Win32.OpenFileDialog tem exatamente a mesma propriedade e a usa como esperado.

Tenho a mesma necessidade.
Você poderia adicionar uma configuração que permita definir o diretório inicial da caixa de diálogo, por favor?
Obrigada.

Eu fui para o código da biblioteca Ookii. então descobri como levar em consideração a propriedade InitialDirectory .
Você deve alterar esta linha de código para o arquivo VistaFileDialog.cs
No método internal virtual void SetDialogProperties(Ookii.Dialogs.Wpf.Interop.IFileDialog dialog)
mude este pedaço de código

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

para

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

Isso é feito.
Agora a caixa de diálogo Ookii iniciará na propriedade InitialDirectory .

Espero que possa ajudar.

@ gitjsdr26 você pode criar um PR para @augustoproiete

@nzain , desculpe, não sei como fazer isso com o GitHub.

Ok, reuni mais algumas informações para lançar luz sobre esse problema.

Falamos sobre uma propriedade InitialDirectory como a documentada para OpenFileDialog.InitialDirectory do WPF. A documentação diz:

Obtém ou define o diretório inicial exibido por uma caixa de diálogo de arquivo.

Os usuários do Ookii Dialogs esperam o mesmo comportamento porque a propriedade tem o mesmo nome. Concordo, em muitas situações esta propriedade não deve ser configurada (notepad etc.), mas isso é outra história. _Se_ a propriedade estiver configurada, ela deve funcionar conforme o esperado.

O InitialDirectory não deve ser confundido com IFileDialog::SetDefaultFolder que é chamado atualmente. Aqui, a documentação diz:

Define a pasta usada como padrão se não houver um valor de pasta usado recentemente disponível.

Não tenho certeza se isso (nenhuma pasta usada recentemente disponível) é o caso. Definir a pasta padrão nunca teve nenhum efeito para mim. Se essa funcionalidade for necessária para qualquer pessoa, ela deve estar disponível como uma propriedade DefaultDirectory . Pode ser um artefato obsoleto dos velhos tempos - se alguém souber quando isso surtiu efeito, por favor, me avise.

PR?

O PR # 2 está aberto há dois anos (!) E sugere algo semelhante. Embora o autor @buildcomplete mencione que está funcionando pelo menos uma vez em seu cenário. Sua correção parece ser baseada em código antigo, mas faz a mesma coisa que @ gitjsdr26 sugere: mude a chamada
IFileDialog::SetDefaultFolder(...) a IFileDialog::SetFolder(...) .

Não quero perder tempo com a criação de RP (eu mudaria essa linha também).

@augustoproiete , diga-nos o que pensa sobre isto :)

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

stricq picture stricq  ·  10Comentários

mgpreston picture mgpreston  ·  4Comentários

mu88 picture mu88  ·  9Comentários

vpenades picture vpenades  ·  4Comentários

matelich picture matelich  ·  3Comentários