まず、ウィンドウを必要としない ShowDialog シグネチャを使用できます。
var dlg = new FolderBrowserDialog();
DialogResult result = dlg.ShowDialog();
次に、アプリケーションのメイン ウィンドウを所有ウィンドウとして送信できます。
var dlg = new FolderBrowserDialog();
DialogResult result = dlg.ShowDialog(Application.Current.MainWindow.GetIWin32Window());
2 番目のオプションは、あまり MVVMish とは見なされない可能性があります。
View へのポインターを ViewModel に挿入する方法については、この質問の@ Dr. ABTによる回答を参照してください (これが良いアイデアか悪いアイデアかはわかりませんが、それで私を止めるつもりはありません)。この手法を使用すると、そのビューを FolderBrowserDialog の所有者にしたい場合は、VM で対応するビューにアクセスできます。
@ChrisDD は、インターフェイスの定義と FolderBrowserDialog のラッピングについて正しいです。それが私たちのやり方です:
public interface IFolderBrowserDialog
{
string Description { get; set; }
Environment.SpecialFolder RootFolder { get; set; }
string SelectedPath { get; set; }
bool ShowNewFolderButton { get; set; }
bool? ShowDialog();
bool? ShowDialog(Window owner);
}
//Decorated for MEF injection
[Export(typeof(IFolderBrowserDialog))]
[PartCreationPolicy(CreationPolicy.NonShared)]
internal class WindowsFormsFolderBrowserDialog : IFolderBrowserDialog
{
private string _description;
private string _selectedPath;
[ImportingConstructor]
public WindowsFormsFolderBrowserDialog()
{
RootFolder = System.Environment.SpecialFolder.MyComputer;
ShowNewFolderButton = false;
}
#region IFolderBrowserDialog Members
public string Description
{
get { return _description ?? string.Empty; }
set { _description = value; }
}
public System.Environment.SpecialFolder RootFolder { get; set; }
public string SelectedPath
{
get { return _selectedPath ?? string.Empty; }
set { _selectedPath = value; }
}
public bool ShowNewFolderButton { get; set; }
public bool? ShowDialog()
{
using (var dialog = CreateDialog())
{
var result = dialog.ShowDialog() == DialogResult.OK;
if (result) SelectedPath = dialog.SelectedPath;
return result;
}
}
public bool? ShowDialog(Window owner)
{
using (var dialog = CreateDialog())
{
var result = dialog.ShowDialog(owner.AsWin32Window()) == DialogResult.OK;
if (result) SelectedPath = dialog.SelectedPath;
return result;
}
}
#endregion
private FolderBrowserDialog CreateDialog()
{
var dialog = new FolderBrowserDialog();
dialog.Description = Description;
dialog.RootFolder = RootFolder;
dialog.SelectedPath = SelectedPath;
dialog.ShowNewFolderButton = ShowNewFolderButton;
return dialog;
}
}
internal static class WindowExtensions
{
public static System.Windows.Forms.IWin32Window AsWin32Window(this Window window)
{
return new Wpf32Window(window);
}
}
internal class Wpf32Window : System.Windows.Forms.IWin32Window
{
public Wpf32Window(Window window)
{
Handle = new WindowInteropHelper(window).Handle;
}
#region IWin32Window Members
public IntPtr Handle { get; private set; }
#endregion
}
次に、FolderBrowser インポート IFolderBrowserDialog を使用する VM/コマンドを作成します。アプリケーションでは、IFolderBrowserDialog.ShowDialog がダイアログを表示します。単体テストでは、IFolderBrowserDialog をモックして、正しいパラメーターで呼び出されたことを確認したり、選択したフォルダーを sut に戻したりして、テストを続行できるようにします。