Che bel mix… sta di fatto che Wpf non ha, tra le tante cose di cui si sente la mancanza, una ForlderBrowserDialog, niente panico! Si può tranquillamente usare quella presente nell’assembly System.Windows.Forms.dll, o, con un po’ più di lavoro, quella nativa Win32; ma non è questo l’oggetto del post.
Dopo avere referenziato l’assembly System.Windows.Forms.dll potete scrivere una cosa del tipo:
String SelectFolderPath( String initialFolder )
{
    using( var dialog = new System.Windows.Forms.FolderBrowserDialog() )
    {
        dialog.ShowNewFolderButton = true;
        dialog.RootFolder = Environment.SpecialFolder.Desktop;
        dialog.SelectedPath = initialFolder;

        if( dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK )
        {
            return dialog.SelectedPath;
        }
    }

    return null;
}
Nulla di che, vero, ma se voleste impostare l’owner, in modo che la dialog sia figlia di una ben precisa Window e non della MainWindow dell’applicazione?
Wpf mette a disposizione per gli scenari di interoperability la classe WindowInteropHelper a cui passare nel costruttore una Window e poter avere l’Handle (IntPtr/HWND) per farci un po’ di belle cose, l’inghippo però è che ShowDialog() si aspetta una IWin32Window e non un handle… anche qui niente panico:
sealed class Win32Window : System.Windows.Forms.IWin32Window
{
    public Win32Window( IntPtr handle )
    {
        this.Handle = handle;
    }

    public IntPtr Handle
    {
        get;
        private set;
    }
}
Implementiamo molto semplicemente l’interfaccia in questione e poi usiamola:
String SelectFolderPath( Window owner, String initialFolder )
{
    using( var dialog = new System.Windows.Forms.FolderBrowserDialog() )
    {
        dialog.ShowNewFolderButton = true;
        dialog.RootFolder = Environment.SpecialFolder.Desktop;
        dialog.SelectedPath = initialFolder;

        var wih = new WindowInteropHelper( owner );
        var w = new Win32Window( wih.Handle );

        if( dialog.ShowDialog( w ) == System.Windows.Forms.DialogResult.OK )
        {
            return dialog.SelectedPath;
        }
    }

    return null;
}
Ottenendo il risultato desiderato.
.m