Come si configura un OpenFileDialog per selezionare le cartelle?


251

In VS .NET, quando si seleziona una cartella per un progetto, viene visualizzata una finestra di dialogo che assomiglia a OpenFileDialog o SaveFileDialog, ma è impostata per accettare solo le cartelle. Da quando ho visto questo ho voluto sapere come è fatto. Sono a conoscenza di FolderBrowserDialog, ma quella finestra di dialogo non mi è mai piaciuta molto. Inizia troppo piccolo e non mi consente di trarre vantaggio dalla possibilità di digitare un percorso.

Sono quasi sicuro che ormai non c'è modo di farlo da .NET, ma sono altrettanto curioso di sapere come farlo anche da codice non gestito. A meno di reimplementare completamente la finestra di dialogo da zero, come si modifica la finestra di dialogo per avere questo comportamento?

Vorrei anche ribadire che sono a conoscenza di FolderBrowserDialog ma a volte non mi piace usarlo, oltre ad essere sinceramente curioso di come configurare una finestra di dialogo in questo modo. Dicendomi di usare il FolderBrowserDialog mi aiuta a mantenere un'esperienza di interfaccia utente coerente ma non soddisfa la mia curiosità, quindi non verrà considerata come una risposta.

Non è nemmeno una cosa specifica di Vista; Ho visto questa finestra di dialogo da VS .NET 2003, quindi è fattibile in Win2k e WinXP. Questo è meno di una domanda "Voglio conoscere il modo corretto di fare questo" e più di una domanda "Sono stato curioso di questo da quando volevo farlo nel VS 2003". Capisco che la finestra di dialogo dei file di Vista abbia un'opzione per farlo, ma ha funzionato in XP, quindi so che hanno fatto qualcosa per farlo funzionare. Le risposte specifiche di Vista non sono risposte, perché Vista non esiste nel contesto della domanda.

Aggiornamento: Sto accettando la risposta di Scott Wisniewski perché si tratta di un campione di lavoro, ma penso che il merito di Serge che punta alla personalizzazione finestra di dialogo (che è certamente brutto da NET ma fa il lavoro) e Mark Ransom per capire che la SM probabilmente ha lanciato una finestra di dialogo personalizzata per questa attività.


7
solo una semplice soluzione da codeproject codeproject.com/Articles/44914/… [La chiave per ottenere OpenFileDialog per selezionare sia i file che le cartelle è impostare le proprietà ValidateNames e CheckFileExists su false (dialog.ValidateNames = false; dialog.CheckFileExists = false) e imposta FileName su una parola chiave speciale per assicurarti che le cartelle vengano selezionate (dialog.FileName = "Selezione cartella";).]
Riju

3
Invia questo come risposta, ha fatto il lavoro per il mio progetto.
CigarDoug,

@Riju dialog.FileName = "Folder Selection"dovrebbe essere dialog.FileName = "Folder Selection."con il periodo finale? comunque non riesco a farlo funzionare in PowerShell al secondo clic di "Apri" in entrambi i modi. Continua a dire che il file non è stato trovato, anche se CheckFileExists è presumibilmente falso
CompagnoJoecool

nvm, in modalità PowerShell dialog.CheckFileExists = 0invece di false ho risolto il mio problema
Compagno Joool

Risposte:


57

Ho una finestra di dialogo che ho scritto chiamata OpenFileOrFolder che consente di aprire una cartella o un file.

Se si imposta il valore AcceptFiles su false, funziona solo in modalità cartella accetta.

Puoi scaricare la fonte da GitHub qui


4
Molto interessante e decisamente complicato come avevo immaginato. Qualche possibilità di annotarlo e sottolineare cosa fa? Questo insieme ad altri commenti mi porta a credere che la SM probabilmente abbia appena avviato il proprio dialogo.
OwenP,

1
Ottengo il seguente errore quando provo a creare la tua soluzione ... sfortunatamente c ++ in nessuno dei miei punti di forza ... Errore 1: impossibile aprire il file "afxres.h".
Ignacio Soler Garcia,

1
@SoMoS e altri con lo stesso problema: nel file WindowsFormsApplication1.csproj modifica la riga 100 in modo che corrisponda alla tua configurazione. Nel mio caso ho dovuto cambiare "9.0" in "10.0" (due volte) e rimuovere "(x86)" (due volte).
RenniePet,

2
Ho scaricato il codice (zip) e trovato il file .h (C) e compilato con errori come impossibile aprire il file 'sal.h'.
Lei Yang

2
Questa soluzione non funziona neanche su VS2010 e VS2017!
AleX_

49

È possibile utilizzare FolderBrowserDialogEx - una derivata riutilizzabile del FolderBrowserDialog incorporato. Questo ti consente di digitare un percorso, anche un percorso UNC. Puoi anche cercare computer o stampanti con esso. Funziona proprio come l'FBD integrato, ma ... meglio.

(EDIT: avrei dovuto sottolineare che questa finestra di dialogo può essere impostata per selezionare file o cartelle.)

Codice sorgente completo (un modulo C # breve). Gratuito. Licenza MS-Public.

Codice per usarlo:

var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
dlg1.Description = "Select a folder to extract to:";
dlg1.ShowNewFolderButton = true;
dlg1.ShowEditBox = true;
//dlg1.NewStyle = false;
dlg1.SelectedPath = txtExtractDirectory.Text;
dlg1.ShowFullPathInEditBox = true;
dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;

// Show the FolderBrowserDialog.
DialogResult result = dlg1.ShowDialog();
if (result == DialogResult.OK)
{
    txtExtractDirectory.Text = dlg1.SelectedPath;
}

7
Scusate se ho offeso, è solo frustrante fare una domanda e precisare "Voglio questa cosa specifica, non queste altre cose" e avere persone che suggeriscono allegramente la cosa non richiesta. Volevo una finestra di dialogo del browser dei file, non una finestra di dialogo del browser delle cartelle.
OwenP,

15
Il modo in cui la domanda è formulata, mi sembra che stia chiedendo una finestra di dialogo per la selezione delle cartelle - non è vero? Comunque, questo è esattamente quello che stavo cercando +1
Tim

Sicuramente la risposta migliore finora
Vasil Popov,

1
Ciò non cambia il fatto, che la risposta è comunque solo una risposta di collegamento. Mostrare come utilizzare il codice ospitato su una risorsa fuori sede cessa di essere utile quando anche quel collegamento diventa temporaneamente o permanentemente non disponibile. Le regole sono lì per un motivo e questo contributo è in conflitto con tali regole.
IIspettabile

1
Ho esaminato questa risposta e apparentemente non fa riferimento a una risorsa fuori sede. Quindi "ogni altra risposta" è chiaramente sbagliata. Se ritieni che io stia reagendo in modo esagerato, forse dovresti sollevare un problema su meta per discutere delle regole. Non lo farò. Li applicherò e basta.
IIspettabile

48

C'è il pacchetto di codici API di Windows. Ha molte cose relative alla shell, inclusa la CommonOpenFileDialogclasse (nello Microsoft.WindowsAPICodePack.Dialogsspazio dei nomi). Questa è la soluzione perfetta: la solita finestra di dialogo aperta con solo le cartelle visualizzate.

Ecco un esempio di come usarlo:

CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();

Purtroppo Microsoft non spedisce più questo pacchetto, ma diverse persone hanno caricato in modo non ufficiale i binari su NuGet. Un esempio può essere trovato qui . Questo pacchetto è solo roba specifico della shell. Se necessario, lo stesso utente ha diversi altri pacchetti che offrono più funzionalità presenti nel pacchetto originale.


1
Non sapevo che fosse presente nel pacchetto di codici API di Windows, grazie per averlo segnalato.
Patrick Klug,

10
La classe CommonOpenFileDialog esiste solo su Windows Vista o versioni successive, quindi genererà un'eccezione sui sistemi operativi precedenti
Rachel,

1
Puoi dirmi come fare riferimento a Windows API Code Pack?
Jeff

1
La Galleria dell'archivio è stata ritirata. , o almeno così dice il link .. Potrebbe essere questo il nuovo posto?
Predefinito

3
A proposito, la classe CommonOpenFileDialog si trova nello spazio dei nomi Microsoft.WindowsAPICodePack.Dialogs (mi ci è voluto un po 'per trovarlo).
morgb,

35

Il pacchetto Ookii.Dialogs contiene un wrapper gestito attorno alla nuova finestra di dialogo del browser delle cartelle (in stile Vista). Si degrada anche con grazia su sistemi operativi meno recenti.


2
Fantastico, è open source con licenza in stile BSD!
Roman Starkov,

7
l'unico problema è che non mi permetterò di utilizzare il profilo client framework .net come destinazione.
Kugel,

2
Soluzione molto bella. Questa è a mio avviso LA risposta migliore. Esattamente quello che cercavo da 3 anni.
Samuel,

1
Un altro problema con questa soluzione: non consente all'utente di incollare un percorso inesistente. Un aspetto secondario, relativamente, ma ancora un peccato.
Roman Starkov,

1
La migliore risposta pratica per coloro che desiderano una OpenFileDialogfinestra di dialogo delle cartelle in stile.
Aqua

27

Meglio usare il FolderBrowserDialog per quello.

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

9
Sono consapevole che è meglio usare un FolderBrowserDialog. Sono curioso di sapere come sia stato fatto, indipendentemente. Il FolderBrowserDialog puzza comunque in molti modi; anche in Vista non ha la barra dei luoghi. Divertente come se fosse meglio MS lo ha evitato finora in 3 versioni VS.
OwenP,

24
FolderBrowserDialog presenta molti problemi di usabilità. Non prenderei in considerazione l'idea di inserirlo in un'applicazione. Vedi il mio post per una finestra di dialogo che ha un'usabilità molto migliore
Scott Wisniewski,

6
FolderBrowserDialog non consente di: - digitare / incollare percorsi completi nel campo di testo in basso - utilizzare la barra "Collegamenti preferiti" su Vista - usare Cerca su Vista
decasteljau

89
Il FolderBrowserDialog è una parte dell'interfaccia utente davvero orribile.
mackenir,

32
Seriamente, gente, PER FAVORE smettete di inserire questo fastidioso dialogo nelle vostre applicazioni. Ha un'interfaccia utente MOLTO MALE, come evidenziato da commenti precedenti.
Roman Starkov,

23

Dopo ore di ricerche ho trovato questa risposta di leetNightShade a una soluzione funzionante .

Ci sono tre cose che credo rendono questa soluzione molto migliore di tutte le altre.

  1. E 'semplice da usare. Richiede solo di includere due file (che possono essere combinati comunque ad uno) nel progetto.
  2. Ritorna al FolderBrowserDialog standard se utilizzato su sistemi XP o precedenti.
  3. L'autore concede il permesso di utilizzare il codice per qualsiasi scopo ritenga opportuno.

    Non esiste una licenza in quanto sei libero di prendere e fare con il codice quello che vuoi.

Scarica qui il codice .


@MattDavis: ho confermato che funziona su .NET Framework 4.0 (sia profilo standard che client). Assicurati di avere sia FolderSelectDialog.cs che Reflector.cs aggiunti al tuo progetto. Una cosa però ... corri su Windows 8? Ho provato su un computer Win7.
Alex Essilfie,

@Alex Essilfie, hai ragione. Devo aver fatto qualcosa di sbagliato nel trascinarlo nel mio progetto. Eliminerò il mio commento precedente per chiarezza.
Matt Davis,

Ho esaminato più opzioni e ho pensato che questa fosse la migliore. Raccomandando.
Jaded,

Ha funzionato in Windows 10 per me. Buona soluzione semplice
David Wilton,

devono rispettare il failover nei sistemi più vecchi
Mike M

17

Exact Audio Copy funziona in questo modo su Windows XP. Viene visualizzata la finestra di dialogo di apertura del file standard, ma il campo del nome file contiene il testo "Il nome file verrà ignorato".

Sto solo indovinando qui, ma sospetto che la stringa venga iniettata nel controllo di modifica della casella combinata ogni volta che viene apportata una modifica significativa alla finestra di dialogo. Finché il campo non è vuoto e i flag di dialogo sono impostati per non verificare l'esistenza del file, la finestra di dialogo può essere chiusa normalmente.

Modifica: è molto più semplice di quanto pensassi. Ecco il codice in C ++ / MFC, puoi tradurlo nell'ambiente che preferisci.

CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this);
dlg.DoModal();

Modifica 2: questa dovrebbe essere la traduzione in C #, ma non sono fluente in C # quindi non spararmi se non funziona.

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.FileName = "Filename will be ignored";
openFileDialog1.CheckPathExists = true;
openFileDialog1.ShowReadOnly = false;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    // openFileDialog1.FileName should contain the folder and a dummy filename
}

Modifica 3: Finalmente ho esaminato la finestra di dialogo in questione, in Visual Studio 2005 (non avevo accesso ad essa in precedenza). Non è la finestra di dialogo aperta del file standard! Se controlli le finestre in Spy ++ e le confronti con un file standard aperto, vedrai che i nomi di struttura e classe non corrispondono. Se guardi da vicino, puoi anche individuare alcune differenze tra i contenuti delle finestre di dialogo. La mia conclusione è che Microsoft ha completamente sostituito la finestra di dialogo standard in Visual Studio per dargli questa funzionalità. La mia soluzione o qualcosa di simile sarà il più vicino possibile, a meno che tu non sia disposto a programmare il tuo da zero.


17

OK, fammi provare a collegare il primo punto ;-) Giocare un po 'con Spy ++ o Winspector mostra che la casella di testo Cartella nella posizione del progetto VS è una personalizzazione della finestra di dialogo standard. Non è lo stesso campo della casella di testo del nome file in una finestra di dialogo di file standard come quella nel Blocco note.

Da quel momento, immagino, VS nasconde le caselle di testo / casella di testo e il tipo di file e utilizza un modello di finestra di dialogo personalizzato per aggiungere la propria parte nella parte inferiore della finestra di dialogo.

EDIT: Ecco un esempio di tale personalizzazione e come farlo (in Win32. Non .NET):

m_ofn è la struttura OPENFILENAME che sta alla base della finestra di dialogo del file. Aggiungi queste 2 righe:

  m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
  m_ofn.Flags |= OFN_ENABLETEMPLATE;

dove IDD_FILEDIALOG_IMPORTXLIFF è un modello di finestra di dialogo personalizzato che verrà aggiunto nella parte inferiore della finestra di dialogo. Vedi la parte in rosso sotto. (fonte: apptranslator.com )testo alternativo

In questo caso, la parte personalizzata è solo un'etichetta + un collegamento ipertestuale ma potrebbe essere qualsiasi finestra di dialogo. Potrebbe contenere un pulsante OK che ci consentirebbe di convalidare la selezione della sola cartella.

Ma come potremmo sbarazzarci di alcuni dei controlli nella parte standard della finestra di dialogo, non lo so.

Maggiori dettagli in questo articolo MSDN .


1
Sembra qualche spiegazione che ho sentito in passato, ma non ho mai visto una dimostrazione del concetto. Ci sono procedure dettagliate nella documentazione MSDN su come farlo?
OwenP,

10

È possibile eseguire la sottoclasse della finestra di dialogo del file e ottenere l'accesso a tutti i suoi controlli. Ognuno ha un identificatore che può essere usato per ottenere la sua maniglia della finestra. È quindi possibile mostrarli e nasconderli, ricevere messaggi da loro sulle modifiche alla selezione, ecc. Ecc. Tutto dipende da quanto sforzo si vuole fare.

Abbiamo fatto il nostro utilizzando il supporto di classe WTL e personalizzato la finestra di dialogo del file per includere una barra dei luoghi personalizzata e viste COM plug-in.

MSDN fornisce informazioni su come eseguire questa operazione utilizzando Win32, questo articolo CodeProject include un esempio e questo articolo CodeProject fornisce un esempio .NET .


10

Puoi usare il codice in questo modo

  • Il filtro è nascondi file
  • Il nome file è nascondi primo testo

Per nascondere in modo avanzato la casella di testo per il nome file, devi guardare OpenFileDialogEx

Il codice:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

Semplice ed è quello di cui ho bisogno per Windows 7+
Hao Nguyen,

Anche OFN_NOVALIDATE è richiesto nelle bandiere
Goblin Alchemist,

5

Presumo che tu sia su Vista usando VS2008? In tal caso, penso che l' opzione FOS_PICKFOLDERS venga utilizzata quando si chiama la finestra di dialogo del file Vista IFileDialog . Temo che nel codice .NET ciò comporterebbe un sacco di codice di interoperabilità P / Invoke gnarly per funzionare.


1
Vista-specifica; L'ho visto per la prima volta su VS 2003 su Windows XP.
OwenP,

2

Prima soluzione

Ho sviluppato questo come una versione ripulita della finestra di dialogo di selezione delle cartelle in stile .NET Win 7 di Bill Seddon di lyquidity.com (non ho affiliazioni). (Ho appreso del suo codice da un'altra risposta in questa pagina ). Ho scritto il mio perché la sua soluzione richiede un'ulteriore classe Reflection che non è necessaria per questo scopo mirato, utilizza il controllo del flusso basato su eccezioni, non memorizza nella cache i risultati delle sue chiamate reflection. Si noti che la VistaDialogclasse statica nidificata è in modo tale che le sue variabili di riflessione statica non provino a essere popolate se il Showmetodo non viene mai chiamato. Ritorna alla finestra di dialogo pre-Vista se non in una versione di Windows abbastanza alta. Dovrebbe funzionare in Windows 7, 8, 9, 10 e versioni successive (teoricamente).

using System;
using System.Reflection;
using System.Windows.Forms;

namespace ErikE.Shuriken {
    /// <summary>
    /// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
    /// </summary>
    public class FolderSelectDialog {
        private string _initialDirectory;
        private string _title;
        private string _fileName = "";

        public string InitialDirectory {
            get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
            set { _initialDirectory = value; }
        }
        public string Title {
            get { return _title ?? "Select a folder"; }
            set { _title = value; }
        }
        public string FileName { get { return _fileName; } }

        public bool Show() { return Show(IntPtr.Zero); }

        /// <param name="hWndOwner">Handle of the control or window to be the parent of the file dialog</param>
        /// <returns>true if the user clicks OK</returns>
        public bool Show(IntPtr hWndOwner) {
            var result = Environment.OSVersion.Version.Major >= 6
                ? VistaDialog.Show(hWndOwner, InitialDirectory, Title)
                : ShowXpDialog(hWndOwner, InitialDirectory, Title);
            _fileName = result.FileName;
            return result.Result;
        }

        private struct ShowDialogResult {
            public bool Result { get; set; }
            public string FileName { get; set; }
        }

        private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title) {
            var folderBrowserDialog = new FolderBrowserDialog {
                Description = title,
                SelectedPath = initialDirectory,
                ShowNewFolderButton = false
            };
            var dialogResult = new ShowDialogResult();
            if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
                dialogResult.Result = true;
                dialogResult.FileName = folderBrowserDialog.SelectedPath;
            }
            return dialogResult;
        }

        private static class VistaDialog {
            private const string c_foldersFilter = "Folders|\n";

            private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
            private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
            private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
            private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
            private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
            private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
            private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialogNative+FOS")
                .GetField("FOS_PICKFOLDERS")
                .GetValue(null);
            private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
                .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
            private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
            private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
            private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");

            public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title) {
                var openFileDialog = new OpenFileDialog {
                    AddExtension = false,
                    CheckFileExists = false,
                    DereferenceLinks = true,
                    Filter = c_foldersFilter,
                    InitialDirectory = initialDirectory,
                    Multiselect = false,
                    Title = title
                };

                var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
                s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
                s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
                var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
                s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);

                try {
                    int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
                    return new ShowDialogResult {
                        Result = retVal == 0,
                        FileName = openFileDialog.FileName
                    };
                }
                finally {
                    s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
                }
            }
        }

        // Wrap an IWin32Window around an IntPtr
        private class WindowWrapper : IWin32Window {
            private readonly IntPtr _handle;
            public WindowWrapper(IntPtr handle) { _handle = handle; }
            public IntPtr Handle { get { return _handle; } }
        }
    }
}

È usato così in un Windows Form:

var dialog = new FolderSelectDialog {
    InitialDirectory = musicFolderTextBox.Text,
    Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
    musicFolderTextBox.Text = dialog.FileName;
}

Ovviamente puoi giocare con le sue opzioni e quali proprietà espone. Ad esempio, consente la selezione multipla nella finestra di dialogo in stile Vista.

Seconda soluzione

Simon Mourier ha dato una risposta che mostra come eseguire esattamente lo stesso lavoro utilizzando l'interoperabilità diretta con l'API di Windows, anche se la sua versione dovrebbe essere integrata per utilizzare la finestra di dialogo di stile precedente se in una versione precedente di Windows. Sfortunatamente, non avevo ancora trovato il suo post quando ho elaborato la mia soluzione. Dai un nome al tuo veleno!


Esempio di utilizzo simile per chiamare questa finestra di dialogo fine come una finestra di dialogo (ad es. Da app di tipo console) con handle vuoto: compila subito la casella: var dialog = new FolderSelectDialog {InitialDirectory = "C: \\", Title = "Seleziona un cartella per importare musica da "}; if (dialog.Show ()) {string myFolder = dialog.FileName; }
Philm,

Nota: il mio esempio di utilizzo come commento è difficile da leggere, quindi: La modifica più importante all'utilizzo originale "esempio": utilizzare una virgola tra InitialDirectory e Title ..
Philm

1

Prova questo da Codeproject (credito a Nitron):

Penso che sia la stessa finestra di cui stai parlando - forse sarebbe d'aiuto se aggiungi uno screenshot?

bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
    bool retVal = false;

    // The BROWSEINFO struct tells the shell how it should display the dialog.
    BROWSEINFO bi;
    memset(&bi, 0, sizeof(bi));

    bi.ulFlags   = BIF_USENEWUI;
    bi.hwndOwner = hOwner;
    bi.lpszTitle = szCaption;

    // must call this if using BIF_USENEWUI
    ::OleInitialize(NULL);

    // Show the dialog and get the itemIDList for the selected folder.
    LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

    if(pIDL != NULL)
    {
        // Create a buffer to store the path, then get the path.
        char buffer[_MAX_PATH] = {'\0'};
        if(::SHGetPathFromIDList(pIDL, buffer) != 0)
        {
            // Set the string value.
            folderpath = buffer;
            retVal = true;
        }       

        // free the item id list
        CoTaskMemFree(pIDL);
    }

    ::OleUninitialize();

    return retVal;
}

images.google.com/… Effettua ricerche se non sei sicuro. Ho descritto quello che volevo e FolderBrowserDialog è già stato squalificato come risposta.
OwenP,

"Sono a conoscenza di FolderBrowserDialog, ma non mi è mai piaciuta molto quella finestra di dialogo. Inizia troppo piccola e non mi consente di trarre vantaggio dalla possibilità di digitare un percorso." Fai qualche ricerca tu stesso - puoi digitare un percorso lì dentro. Comunque penso che sia una domanda un po 'ambigua, quindi buona fortuna.
demoncodemonkey,

@demoncodemonkey: non è possibile digitare una parte del percorso e quindi navigare verso la destinazione desiderata. Di gran lunga non conveniente come le opzioni offerte da FileOpenDialog.
Treb

1

Su Vista puoi usare IFileDialog con l'opzione FOS_PICKFOLDERS impostata. Ciò causerà la visualizzazione di una finestra simile a OpenFileDialog in cui è possibile selezionare le cartelle:

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

Per Windows più vecchi puoi sempre ricorrere a trucchi per selezionare qualsiasi file nella cartella.

Qui puoi trovare un esempio funzionante che funziona su .NET Framework 2.0 e versioni successive .


1

Puoi usare il codice in questo modo

Il filtro è una stringa vuota. Il nome file è AnyName ma non è vuoto

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

6
So che questo è un vecchio post, ma per il bene di chiunque voglia provarlo, in realtà non funziona a meno che la directory che si desidera aprire non abbia assolutamente directory secondarie. Quindi, se voglio consentire al mio utente di cercare una cartella e selezionarla e popolare il percorso della cartella in una casella di testo, l'utente non potrà mai selezionare C: \ SomeParentDir se esiste la directory C: \ SomeParentDir \ SomeChildDir, perché selezionando "Apri "ti porta semplicemente nella directory figlio.
Jim,

Bel tentativo .. ma questo si traduce in un'interfaccia utente terribile come "AnyFile" nella casella di testo sta solo aspettando che l'utente sovrascriva il suo testo .. a parte questo, l'utente può anche selezionare i file - non abbastanza bene. ma bello provare ..
GY


-1

So che la domanda era sulla configurazione di OpenFileDialogma vedendo che Google mi ha portato qui, posso anche sottolineare che se stai cercando SOLO cartelle dovresti usare un FolderBrowserDialogInvece come risposta da un'altra domanda SO qui sotto

Come specificare il percorso utilizzando la finestra di dialogo Apri file in vb.net?


Ingannevole. 1) E ' non è l'unica scelta; 2) Non è una buona scelta nella maggior parte dei casi; Tuttavia richiede il minimo codice, scambiato da più tempo trascorso dall'utente finale.
Meow Cat 2012,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.