我正在开发一个 WPF 项目,该项目是代码隐藏 xaml/xaml.cs 和一些不太完整的 ViewModel 的混搭。
(免责声明:直到最近,我在 WPF 方面的经验还很少。我可以相当熟练地设计和布局 Window 或 UserControl,而且我认为我掌握了将 MVVM ViewModel 从 View 中分离出来并进行绑定(bind)的窍门接线,但这是我目前使用 WPF 的经验的限制。)
我的任务是为程序添加一些新功能,因此看起来需要先将其转换为正确使用 MVVM。
我将展示我面临的一个具体问题:
有一个 View 叫做 SettingsWindow.xaml
我正在使用的。它是一组文本框、标签等等。我已将所有 View 数据剥离到 ViewModel
中。类似于这样的类:
class SettingsViewModel : ViewModelBase {
private String _outputDirectory;
public String OutputDirectory {
get { return _outputDirectory; }
set { SetValue( () => this.OutputDirectory, ref _outputDirectory, value) ); }
}
// `SetValue` calls `PropertyChanged` and does other common-tasks.
// Repeat for other properties, like "Int32 Timeout" and "Color FontColor"
}
在原来的 ViewModel 类中有 2 个方法:
ReadFromRegistry
和 SaveToRegistry
. ReadFromRegistry
方法由 ViewModel 的构造函数调用,SaveToRegistry
方法被 MainWindow.xaml.cs
调用的代码隐藏如下:private void Settings_Click(Object sender, RoutedEventArgs e) {
SettingsViewModel model = new SettingsViewModel(); // loads from registry via constructor
SettingsWindow window = new SettingsWindow();
window.Owner = this;
window.DataContext = model;
if( dialog.ShowDialog() == true ) {
model.SaveToRegistry();
}
}
...但这对我来说似乎是错误的。我认为 ViewModel 应该只包含一个用于绑定(bind)目的的可观察数据包,它不应该负责自我填充或持久性,这是 Controller 或其他一些协调器的责任。
我已经阅读了几天关于 MVVM 的文章,我读过的文章都没有提到 Controller 或打开子窗口或保存状态的逻辑应该去哪里。我看过一些文章确实将代码放在 ViewModel 中,其他人继续为此使用代码隐藏,其他人抽象出所有内容并使用
IService
基于 - 的解决方案,这对我来说是 OTT。鉴于这是一个转换项目,我将随着时间的推移单独转换每个窗口/ View ,我无法真正对其进行大修,但我可以从这里去哪里? MVVM 中的 Controller 到底长什么样? (我为模糊的术语道歉,现在是凌晨 3 点 :))。
我重构的目的是分离关注点;可测试性不是目标,也不会实现。
最佳答案
我个人不同意在我的 ViewModels 中添加与 View 相关的东西(毕竟,它是 View 的模型!)
所以我使用了一个 Controller 范例,当 View 告诉 View 模型执行一些操作(通常通过命令)并且 View 模型使用命令类来执行操作时,例如保存数据、实例化新的 View / View 模型对等。
我实际上也将我的 ViewModel 和 ViewData 分开(ViewModel“包含”ViewData),因此 ViewData 只处理数据,ViewModel 具有一些逻辑和命令处理等。
I wrote about it here
关于wpf - MVVM Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19465036/