Pokud potřebujete v .NET vyvolat dialog pro výběr adresáře ve Windows desktopových (těžkých) aplikacích tak to samozřejmě můžete udělat přímo zabudovanými prostředky .NET Frameworku. Ale bude to ten správný standardní Windows dialog?
Pro vyvolání dialogu na výběr adresáře najdeme v .NETu třídu FolderBrowserDialog. S tím je ale problém, protože tato třída se v .NETu nachází pouze jako součástí technologie Windows Forms (*) a je tam bohužel nezměněna již od verze FW 1.1. Podívejte se, jak takto vyvolaný dialog vypadá.
Přiznejme si, že toto je na dnešní dobu poměrně špatně nedesignované uživatelské UI. Největší nevýhoda je asi to, že do dialogu nejde cestu vložit či vykopírovat, nebo nelze použít jiné zobrazení, náhledy, hledání, favorites atd.
Pozn.: To že je FolderBrowserDialog pouze ve WinForms a tedy pro tento dialog potřebujete v aplikacích ve WPF přidat do referencí i System.Windows.Forms assembly za problém osobně nepovažuji. Reference by vadit neměla, je stejně součástí .NETu, který se musí nainstalovat celý (WPF i Windows.Forms jsou součástí Client Profile) a shodná jména tříd ošetříme uvedením konkrétních namespace.
Tento dialog byl v Systému Windows Vista a novější nahrazen jiným novým dialogem, který vychází graficky z open dialogu, vypadá takto. (Asi jste tento nový dialog už všichni někdy použili např. pokud vybíráte adresář pro nový projekt ve VS).
Aby jsme nový dialog vyvolali, je ale potřeba použít jiného API, které je doplněno od Visty (konkrétně se jedná o volání přes COM interface IFileDialog). Volání původní API funkce SHBrowseForFolder totiž nový dialog automaticky nezobrazí na rozdíl od toho, jak tomu částečně je u open a save dialogů (**).
Pozn.: Ve skutečnosti se ve Vista API dialog pro výběr adresářů nevolá žádnou speciální funkcí, ale jedná se o funkci pro open dialog, kterému se nastaví příznak FOS_PICKFOLDERS (***).
Osobně mi přijde docela škoda, že takovéto věci jako je volání tohoto dialogu přes nové API Microsoft do .NET Frameworku sám nezapracuje, když Vista už tady nějakou dobu je. (A sám Microsoft ve svých aplikací tento dialog používá.)
Pro zavolání dialogu jsem připravil třídu, nejprve si ještě ale shrňme požadavky, které jsem na ní měl:
- Třída bude na Windows Vista a novějších volat nový dialog a na starších operačních systémech se provede automatický fallback na nějaký dialog v tomto systému.
- Třída bude mít jednotný interface pro klasický i nový dialog, tj. nemá žádné vlastnosti, které chodí např. pouze pro jeden z dialogů.
- Celé řešení je oddělené a ne pouze součásti velkého balíku tříd nebo knihovny (****).
Řešení se skládá z těchto souborů:
Druhou možností je stáhnou si kompletní VS projekt včetně testovacího programu zde.
Ještě odkaz na diskuzi na stackoverflow, ze které jsem pro tento článek čerpal některé informace.
(*) Na rozdíl od FolderBrowser dialogu jsou totiž např. open a save dialogová okna kromě Windows Forms implementována znovu pro WPF v samostatném namespace Microsoft.Win32.
(**) U standardního open a save dialogu je zobrazen nový Windows Vista / 7 vzhled i při volání starší funkcí, GetOpenFileName ale pouze v případě, pokud nepoužijeme příznak OFN_ENABLEHOOK. Při použití hook procedury totiž mohl být výchozí vzhled dialog pozměněn a tak nemusí být kompatibilní s novým vzhledem, a tak je zobrazen vzhled starý (vzhled Windows XP). V .NETu funkce na open a save dialog ve WPF hook používají, a proto byl např. dialog ve FW 3.5 zobrazen špatně. Nyní v .NET 4.0 je nejprve zjištěna verze operačního systému a podle toho je buď zobrazen dialog postaru (Windows XP), nebo je přes nové Vista API zobrazen dialog nový. (Nové API také podporuje hook, ale je už daleko přísnější, takže vzhled dialogu nelze tolik změnit).
(***) K příznaku FOS_PICKFOLDERS se vztahuje taková zajímavost, ve Windows Vista bylo totiž možné tento příznak uvést i u save dialogu, to bylo ve Windows 7 změněno, a příznak tedy už funguje pouze u open dialogu.
(****) Existují i některé knihovny, ve kterých je Browse for folder dialog řešen
- WindowsAPICodePack – Knihovna pro volání některých nových funkcí Windows Vista / 7. Obsahuje třídu pro open dialog, který se dá vyvolat i v režimu Folder Picker. Knihovna je pouze pro nové API, na starších systémech je vyhozena exception.
- Ookii.Dialogs – Knihovna pro FW 3.5 s některými novými Vista dialogy. Obsahuje i zpětnou kompatibilitu pro starší systémy.