Seleziona la cartella di dialogo WPF

Sviluppo un’applicazione WPF4 e nella mia app devo consentire all’utente di selezionare una cartella in cui l’applicazione memorizzerà qualcosa (file, report generati, ecc.).

I miei requisiti:

Come ho capito, fino al 2010 (.Net 4.0) non ci sarà una finestra di dialogo standard, ma forse ci sono alcuni cambiamenti nella versione 4.0?

O tutto ciò che resta da fare è usare la finestra di dialogo di WinForms vecchia scuola? Se è l’unico modo per fare ciò di cui ho bisogno, come posso renderlo più vicino allo stile Vista / 7 e non a Win9x?

Su alcuni forum, ho visto l’implementazione di tali windows di dialogo ma con vecchie icone brutte à la Windows 95. Non sembra davvero bello.

Ne ho scritto molto sul mio blog molto tempo fa, il supporto di WPF per le windows di dialogo dei file comuni è davvero pessimo (o almeno lo era in 3.5 Non ho controllato la versione 4) – ma è facile aggirarlo.

Devi aggiungere il manifest corretto alla tua applicazione – questo ti darà un messaggio di stile moderno e un browser di cartelle (WinForms FolderBrowserDialog) ma non i dialoghi di apertura / salvataggio di file WPF, questo è descritto in quei 3 post (se non ti interessa riguardo alla spiegazione e voglio solo che la soluzione vada direttamente al terzo):

  • Perché sto recuperando windows di dialogo e windows di messaggi con WPF
  • L’impostazione di un manifesto risolve i problemi di stile della casella di messaggio WPF?
  • Il manifest di applicazione necessario per XP e Vista File di dialogo di stile e caselle di messaggio con WPF

Fortunatamente, le windows di dialogo di apertura / salvataggio sono involucri molto sottili intorno all’API Win32 che è facile da chiamare con i giusti flag per ottenere lo stile Vista / 7 (dopo aver impostato il manifest)

  • Stile Vista apre e salva le windows di dialogo con WPF (senza utilizzare l’esempio del bridge Vista)

Il libro di ricette di Windows Presentation Foundation 4.5 di Pavel Yosifovich a pagina 155 nella sezione “Uso delle windows di dialogo comuni” dice:

“Che ne è della selezione della cartella (anziché dei file)? WPF OpenFileDialog non supporta questa soluzione Una soluzione consiste nell’utilizzare la class FolderBrowseDialog di Windows Form. Un’altra buona soluzione consiste nell’utilizzare il pacchetto di codice dell’API di Windows descritto a breve.”

Ho scaricato il pacchetto di codice API da Windows® API Code Pack per Microsoft® .NET Framework Codice di Windows API Pack: dov’è? , quindi aggiunto riferimenti a Microsoft.WindowsAPICodePack.dll e Microsoft.WindowsAPICodePack.Shell.dll al progetto WPF 4.5.

Esempio:

using Microsoft.WindowsAPICodePack.Dialogs; var dlg = new CommonOpenFileDialog(); dlg.Title = "My Title"; dlg.IsFolderPicker = true; dlg.InitialDirectory = currentDirectory; dlg.AddToMostRecentlyUsedList = false; dlg.AllowNonFileSystemItems = false; dlg.DefaultDirectory = currentDirectory; dlg.EnsureFileExists = true; dlg.EnsurePathExists = true; dlg.EnsureReadOnly = false; dlg.EnsureValidNames = true; dlg.Multiselect = false; dlg.ShowPlacesList = true; if (dlg.ShowDialog() == CommonFileDialogResult.Ok) { var folder = dlg.FileName; // Do something with selected folder string } 

Microsoft.Win32.OpenFileDialog è la finestra di dialogo standard utilizzata da qualsiasi applicazione su Windows. Il tuo utente non sarà sorpreso dal suo aspetto quando utilizzi WPF in .NET 4.0

Il dialogo è stato modificato in Vista. WPF in .NET 3.0 e 3.5 utilizzava ancora la finestra di dialogo legacy ma era stata risolta in .NET 4.0. Posso solo immaginare che hai iniziato questo thread perché stai vedendo quella vecchia finestra di dialogo. Il che probabilmente significa che stai effettivamente eseguendo un programma che ha come target 3.5. Sì, il wrapper Winforms ha ottenuto l’aggiornamento e mostra la versione di Vista. Classe System.Windows.Forms.OpenFileDialog, è necessario aggiungere un riferimento a System.Windows.Forms.

MVVM + WinForms FolderBrowserDialog come comportamento

 public class FolderDialogBehavior : Behavior 

uso

   

Blogpost: http://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html

Aggiungi il codice API Windows Pack-Shell al tuo progetto

 using Microsoft.WindowsAPICodePack.Dialogs; ... var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; CommonFileDialogResult result = dialog.ShowDialog(); 

In base alla risposta di Oyun, è meglio utilizzare una proprietà di dipendenza per FolderName. Ciò consente (per esempio) l’associazione a sotto-proprietà, che non funziona nell’originale. Inoltre, nella mia versione modificata, la finestra di dialogo mostra seleziona la cartella iniziale.

Utilizzo in XAML:

  

Codice:

 using System.Windows; using System.Windows.Forms; using System.Windows.Interactivity; using Button = System.Windows.Controls.Button; public class FolderDialogBehavior : Behavior 

Se non si desidera utilizzare Windows Form o modificare file manifest, mi è venuto in mente un attacco molto semplice che utilizza la finestra di dialogo SaveAs di WPF per selezionare effettivamente una directory.

Non è necessario utilizzare la direttiva, puoi semplicemente copiare e incollare il codice qui sotto!

Dovrebbe comunque essere molto user-friendly e la maggior parte delle persone non se ne accorgerà mai.

L’idea deriva dal fatto che possiamo cambiare il titolo di quella finestra di dialogo, hide i file e aggirare il nome del file risultante abbastanza facilmente.

È sicuramente un grosso problema, ma forse farà il lavoro per il tuo utilizzo …

In questo esempio ho un object textbox per contenere il percorso risultante, ma puoi rimuovere le linee correlate e usare un valore di ritorno se vuoi …

 // Create a "Save As" dialog for selecting a directory (HACK) var dialog = new Microsoft.Win32.SaveFileDialog(); dialog.InitialDirectory = textbox.Text; // Use current value for initial dir dialog.Title = "Select a Directory"; // instead of default "Save As" dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files dialog.FileName = "select"; // Filename will then be "select.this.directory" if (dialog.ShowDialog() == true) { string path = dialog.FileName; // Remove fake filename from resulting path path = path.Replace("\\select.this.directory", ""); path = path.Replace(".this.directory", ""); // If user has changed the filename, create the new directory if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } // Our final value is in path textbox.Text = path; } 

Gli unici problemi con questo hack sono:

  • Il pulsante Riconosci dice ancora “Salva” invece di qualcosa come “Seleziona directory”, ma in un caso come miniere “Salva” la selezione della directory in modo che funzioni ancora …
  • Il campo di immissione dice ancora “Nome file” invece di “Nome directory”, ma possiamo dire che una directory è un tipo di file …
  • C’è ancora un menu a discesa “Salva come”, ma il suo valore dice “Directory (* .this.directory)”, e l’utente non può cambiarlo per qualcos’altro, funziona per me …

La maggior parte delle persone non se ne accorgerà, anche se preferirei sicuramente usare un metodo WPF ufficiale se microsoft si togliesse la testa dal culo, ma fino a quando non lo faranno, questa è la mia soluzione temporanea.

Solo tale finestra di dialogo è FileDialog . Fa parte di WinForms, ma è in realtà solo wrapper attorno alla finestra di dialogo del file OS standard di WinAPI. E non penso che sia brutto, è in realtà parte del sistema operativo, quindi sembra che il sistema operativo sia gestito.

In altro modo, non c’è nulla per aiutarti. O hai bisogno di cercare l’implementazione di terze parti, sia gratis (e non penso che ci sia nulla di buono) o pagato.