我正在开发一个 WPF 项目,该项目是代码隐藏 xaml/xaml.cs 和一些不太完整的 ViewModel 的混搭。
(免责声明:直到最近,我在 WPF 方面的经验还很少。我可以相当熟练地设计和布局 Window 或 UserControl,而且我认为我掌握了将 MVVM ViewModel 从 View 中分离出来并进行绑定的窍门接线,但这是我目前使用 WPF 的经验的限制。)
我的任务是为程序添加一些新功能,这样看起来就需要先将其转换为正确使用 MVVM。
我将展示我面临的一个具体问题:
有一个名为SettingsWindow.xaml
我正在使用的视图。它是一组文本框、标签等等。我已将所有视图数据剥离到一个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 应该只包含一个用于绑定目的的可观察数据包,它不应该负责自我填充或持久性,这是控制器或其他一些协调器的责任。
我已经读了几天关于 MVVM 的文章,我读过的文章都没有提到控制器或打开子窗口或保存状态的逻辑应该去哪里。我已经看到一些文章确实将该代码放入 ViewModel 中,其他人继续为此使用代码隐藏,其他人抽象出所有内容并使用IService
基于 - 的解决方案,这对我来说是 OTT。
鉴于这是一个转换项目,我将随着时间的推移单独转换每个窗口/视图,我无法真正对其进行大修,但我可以从这里去哪里?MVVM 中的控制器到底长什么样?(我为模糊的术语道歉,现在是凌晨 3 点 :))。
我重构的目的是分离关注点;可测试性不是目标,也不会实施。