MVVM的控制器

Dai*_*Dai 2 wpf model-view-controller controller mvvm

我正在一个WPF项目中,该项目杂乱地隐藏在xaml / xaml.cs和一些不十分流行的ViewModels背后。

(免责声明:直到最近,我对WPF的了解还很少。我可以相当熟练地设计和布局Window或UserControl,我认为我可以将MVVM ViewModel与View分离并进行绑定。连线,但这是我目前使用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"
}
Run Code Online (Sandbox Code Playgroud)

在原始的ViewModel类中,有2种方法:ReadFromRegistrySaveToRegistry。该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();
    }
}
Run Code Online (Sandbox Code Playgroud)

...但这对我来说似乎是错的。我认为ViewModel应该只包含一个可观察的数据包以用于绑定目的,它不应对自我填充或持久性负责,这是控制器或其他协调器的责任。

我已经花了几天的时间来阅读有关MVVM的文章,并且我所读的文章都没有提到控制器或打开子窗口或保存状态的逻辑应该放在哪里。我看过一些确实将代码放入ViewModels中的文章,另一些文章继续为此使用代码,另一些文章则将所有内容抽象化并使用IService基于解决方案的方法,这对我来说就是OTT。

鉴于这是一个转换项目,我将在一段时间内逐个转换每个Window / View,因此我无法真正对其进行全面检查,但是从这里可以去哪里呢?MVVM中的Controller到底是什么样的?(我对模糊的术语表示歉意,现在是凌晨3点:))。

我重构的目的是将关注点分开;可测试性不是目标,也不是可以实现的。

Max*_*xxx 5

我个人不同意在ViewModels中放置过多与View相关的内容(毕竟,这是View的模型!)

因此,我使用Controller范式,即当View告诉ViewModel执行某些操作时(通常通过Command进行操作),而ViewModel使用Command类执行操作,例如保存数据,实例化新的View / Viewmodel对等。

我实际上也将ViewModel和ViewData分开了(ViewModel“包含”了ViewData),因此ViewData巧妙地处理了数据,ViewModel具有一些逻辑和命令处理等。

我在这里写过