Jie*_*eng 2 c# wpf mvvm mvvm-foundation
我只是想知道这是在MVVM中显示对话框的方式吗?
public ICommand OpenFileCommand
{
get
{
if (_openFileCommand == null) {
_openFileCommand = new RelayCommand(delegate
{
var strArr = DialogsViewModel.GetOpenFileDialog("Open a file ...", "Text files|*.txt | All Files|*.*");
foreach (string s in strArr) {
// do something with file
}
});
}
return _openFileCommand;
}
}
public class DialogsViewModel {
public static string[] GetOpenFileDialog(string title, string filter)
{
var dialog = new OpenFileDialog();
dialog.Title = title;
dialog.Filter = filter;
dialog.CheckFileExists = true;
dialog.CheckPathExists = true;
dialog.Multiselect = true;
if ((bool)dialog.ShowDialog()) {
return dialog.SafeFileNames;
}
return new string[0];
}
}
Run Code Online (Sandbox Code Playgroud)
如果是这样,我应该如何允许自己说修改我正在显示的对话框上的选项.例如,我希望另一个对话框具有不同的对话框选项,dialog.something = something_else而不向我的方法添加很多参数
不应在ViewModel中显示对话框本身.我通常提供一个对话服务接口IDialogServices,具有适当的Dialog方法调用.然后,我有一个View类(通常是MainWindow)实现此接口并执行实际的Show逻辑.这将ViewModel逻辑与特定View隔离开来,例如,允许您对想要打开对话框的代码进行单元测试.
然后,主要任务是将服务接口注入需要它的ViewModel.如果您有依赖注入框架,这是最简单的,但您也可以使用服务定位器(可以注册接口实现的静态类)或通过其构造函数将接口传递给ViewModel(取决于ViewModel的方式)是建造的.)
我认为使用DialogService是一种重量级的方法.我喜欢使用Actions/Lambdas来处理这个问题.
您的视图模型可能将此作为声明:
public Func<string, string, dynamic> OpenFileDialog { get; set; }
Run Code Online (Sandbox Code Playgroud)
然后调用者将创建您的视图模型,如下所示:
var myViewModel = new MyViewModel();
myViewModel.OpenFileDialog = (title, filter) =>
{
var dialog = new OpenFileDialog();
dialog.Filter = filter;
dialog.Title = title;
dynamic result = new ExpandoObject();
if (dialog.ShowDialog() == DialogResult.Ok) {
result.Success = true;
result.Files = dialog.SafeFileNames;
}
else {
result.Success = false;
result.Files = new string[0];
}
return result;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以这样称呼它:
dynamic res = myViewModel.OpenFileDialog("Select a file", "All files (*.*)|*.*");
var wasSuccess = res.Success;
Run Code Online (Sandbox Code Playgroud)
这种方法真的为测试带来了回报.因为您的测试可以将视图模型的返回定义为他们喜欢的任何内容:
myViewModelToTest.OpenFileDialog = (title, filter) =>
{
dynamic result = new ExpandoObject();
result.Success = true;
result.Files = new string[1];
result.Files[0] = "myexpectedfile.txt";
return result;
};
Run Code Online (Sandbox Code Playgroud)
就个人而言,我发现这种方法是最简单的.我会喜欢别人的想法.
| 归档时间: |
|
| 查看次数: |
2827 次 |
| 最近记录: |