C# WPF(MVVM):将现有;组件";/&引用;“应用程序逻辑”在模型或视图模型中
我在WinForms编码方面有一些经验,但我正在尝试使用WPF(和mvvm模式)来完成我的新工作。 我在互联网上搜索了好几天,其中一件事就是获得以下正确信息: 我必须在模型中实现什么,在viewmodel中实现什么,当它转到“管理存储库(模型?)数据”时 (我认为)我确实理解mvvm的基本概念,并对所有数据进行了分解,但我很难找到正确的实现方法 让我们假设我有一个现有的服务(没有任何UI的应用程序),它能够从(ini)配置文件中读取值,做一些它想要做的事情,并将配置写入本地注册表。也许将来我希望将配置更改为存储在xml或json中,而不是ini中。从我的观点来看,这些都很好地放在了现有的代码中——比方说一个带有类configurations的configuration.cs文件——它目前与我下一步要实现的新wpf控制台应用程序毫无关系C# WPF(MVVM):将现有;组件";/&引用;“应用程序逻辑”在模型或视图模型中,c#,wpf,mvvm,C#,Wpf,Mvvm,我在WinForms编码方面有一些经验,但我正在尝试使用WPF(和mvvm模式)来完成我的新工作。 我在互联网上搜索了好几天,其中一件事就是获得以下正确信息: 我必须在模型中实现什么,在viewmodel中实现什么,当它转到“管理存储库(模型?)数据”时 (我认为)我确实理解mvvm的基本概念,并对所有数据进行了分解,但我很难找到正确的实现方法 让我们假设我有一个现有的服务(没有任何UI的应用程序),它能够从(ini)配置文件中读取值,做一些它想要做的事情,并将配置写入本地注册表。也许将来我希望
namespace ExistingConfigurationCode
{
public enum Setting
{
some,
values
}
public class ConfigurationItemProperties
{
public property1
public property 2
}
public class ApplicationConfiguration
{
List<ConfigurationItemProperties> config;
public void LoadConfig()
public void SaveConfig()
}
}
命名空间现有配置代码
{
公共枚举设置
{
一些
价值观
}
公共类配置TempProperty
{
公共财产1
公共财产2
}
公共类应用程序配置
{
列表配置;
公共void LoadConfig()
public void SaveConfig()
}
}
如前所述,现在我确实希望实现一个UI,使用户能够设置这些配置
因为到目前为止我所了解的是:
- 视图只是视图,不包含任何逻辑
- viewmodel负责将所有需要的信息“传递”到视图,并从视图接收命令
- 该模型是我们正在处理的数据的模型
- 这个现有的类已经是我的模型了吗?但是在这个类中添加所有RaisePropertyChange内容是没有意义的,因为它也在服务中使用。我也看过很多教程,其中告诉我不要在模型中放置任何代码
- 如果现有类应该在我的视图模型中,那么我需要该模型做什么
- 模型是否应该只引用我已经存在的类,并通过某种包装器控制对registry/xml/ini的所有读写操作
- 我必须在哪里添加“RaisePropertyChange”getter和setter?因为它们“控制”了UI,我想它们应该放在视图模型中,但是我已经看到了很多例子,它们也在模型中
(我认为)我对管理控制台很满意,因为它可以查看ConfigurationTemproperty的所有属性,所以我可以按照Fabios的第一个解释进行操作。 但是最终用户的第二个UI应该有一个精简的UI,可能是一个列表视图,每个列表视图项都有一些复选框。这是我的问题。
对于listview,我需要ObservableCollection,但是对于列表视图中的项目,我需要前面提到的fabio“facade”。到目前为止我说的对吗
如果是这样,ObservableCollection和“ConfigurationTempropertiesFacade”将与没有任何INotifyPropertyChanged或INotifyCollectionChanges实现的“模型”一起工作。但是我认为“集合”必须是指外观中的“单个项”,因为集合(来自视图模型)在视图模型中没有对外观的引用。试着考虑一下
MVVM
比如应用程序的三层(不是文件)
- 视图-仅包含视图逻辑(XAML和代码)的命名空间/项目 后面)
- 模型-包含所有“业务逻辑”的命名空间/项目
- ViewModel-命名空间/项目,其中包含链接视图和
在不知道视图名称空间的情况下进行建模。换句话说,ViewModel层的职责是在模型和视图之间架起一座桥梁-调用模型的方法,在某些值发生更改时引发
事件,以通知视图有关更改PropertyChanged
public class ConfigurationItemPropertiesFacade : INotifyPropertyChanged
{
private ConfigurationItemProperties _Model;
public string Property1
{
get { return _Model.Property1; }
set
{
if(Equals(_Model.Property1, value)) return;
_Model.Property1 = value;
RaisePropertyChanged();
}
}
public ConfigurationItemPropertiesFacade(ConfigurationItemProperties model)
{
_Model = model;
}
}
使用ConfigurationTempropertiesFacade
class作为视图中的视图模型。通过这种方法,模型层保持干净,可以在任何地方使用 回应评论:
因此,告诉它不允许在模型中放置“代码”的教程是错误的,对吗?
再次尝试在
MVVM
中考虑Model
,它不像一个类/文件,而是可以包含多个类的层/命名空间/项目。没有对错之分——您可以在更好地满足您的规范的同时实现您的逻辑。但是如果您尊重单一责任原则(),那么您将把
应用程序配置
的责任分离到(我不知道方法加载
和保存
的内部逻辑)
- 仅表示数据的“Model”类,没有
功能只是用于保存数据的属性。
你已经有了这个
Co
public class ViewModel { private readonly LoadService _LoadService; private readonly SaveService _SaveService; //Here you can use your"Facade" implementation private ObservableCollection<ConfigurationItemPropertiesFacade> _Items public ObservableCollection<ConfigurationItemPropertiesFacade> Items { get { return _Items; } set { _Items = value; RaisePropertyChanged(nameOf(Items)); } } public ICommand Save { get; set; } public ICommand Load { get; set; } public ViewModel(LoadService loadService, SaveService saveService) { _LoadService = loadService; _SaveService = saveService; // Create command instance for Save // Create command instance for Load var itemsList = _LoadService.Load(); var facadeItems = itemsList.Select(item => new ConfigurationItemPropertiesFacade(item)); Items = new ObservableCollection(facadeItems); } }