C# 具有复杂模型的MVVM

C# 具有复杂模型的MVVM,c#,wpf,mvvm,C#,Wpf,Mvvm,当使用MVVM模式时,当模型对象变得复杂时,即当它们包含非原始/非内置属性时,我会遇到一些麻烦。在我的特定实例中,我有一个ModelA,其中包含ModelB对象的集合,该对象本身包含ModelC对象的集合: class ModelA { public string Name { get; set; } public OberservableCollection<ModelB> Bs { get; set; } } class ModelB { public

当使用MVVM模式时,当
模型
对象变得复杂时,即当它们包含非原始/非内置属性时,我会遇到一些麻烦。在我的特定实例中,我有一个
ModelA
,其中包含
ModelB
对象的集合,该对象本身包含
ModelC
对象的集合:

class ModelA
{
    public string Name { get; set; }
    public OberservableCollection<ModelB> Bs { get; set; }
}

class ModelB
{
    public string Make { get; set; }
    public ObservableCollection<ModelC> Cs { get; set; }
}

class ModelC
{
    public string Brand{ get; set; }
}
我被告知,这不是MVVM做事的方式,每个实体,即
ModelB
ModelC
都应该有自己的
ViewModel
。我被告知保留
Model
类,但为它们创建
ViewModel
s。我无法想象这将如何运作

如果我创建一个
ModelBViewModel

public class ModelBViewModel
{
     ModelB MyModelB { get; set; }
}
我有一个困境-我在
ModelA
类中已经有了
ModelB
实例,现在我在
ModelBViewModel
中还有其他
ModelB
实例。是否有必要在
ModelA
中迭代原始
ModelB
集合并创建
ModelBViewModel
s,同时将
MyModelB
属性设置为与
ModelA
中的属性相匹配?对于应该相当简单的内容来说,这似乎有点复杂?

MVVM的意思是“模型-视图-模型”。如您所见,该名称包含Model和ViewModel。我们的想法是为您拥有的每个模型类提供一个专用的ViewModel类

ViewModel应该包含视图特定的属性和逻辑,而Model类应该包含业务模型特定的属性和逻辑

而且:是的,对于一些非常简单的MVVM示例来说,这可能是开销。然而,一旦您的视图逻辑开始偏离您的业务逻辑,您就会从这种分离中获益

如果有必要遍历原始属性:我会说:是的! 我通常是这样做的:

public class ModelBViewModel
{
    private ModelB _model;

    public ObservableCollection<ModelCViewModel> CVms { get; set; }

    public ModelBViewModel(ModelB model) {
        _model = model;
        CVms = new ObservableCollection();
        foreach(var modelC in model.Cs) {
            CVms.Add(new ModelCViewModel(modelC));
        }
    }
}
公共类ModelBViewModel
{
私有模型b_模型;
公共ObservableCollection CVms{get;set;}
公共模型VIEWMODEL(模型B模型){
_模型=模型;
CVms=新的可观测集合();
foreach(model.Cs中的var modelC){
添加(新模型CVIEWMODEL(模型C));
}
}
}

使用Linq:
CVms=newobserveCollection(model.Cs.Select(c=>newmodelcviewmodel(c))我一直认为应该为每个视图创建ViewModel,而不是为每个模型创建ViewModel。否则,除了MVCYE之外,它还有什么好处呢?您应该为每个视图创建一个视图模型。但是,当您希望在多个视图中显示模型数据时,如果每个模型都有一个视图模型,则可以更轻松地重用视图模型代码。@makzr您是否有一个更大的示例将您在此处编写的内容放在上下文中?我有一个与OP几乎完全相同的问题,我也觉得手动迭代集合为每个模型实例创建一个VM似乎很笨拙,比如说,设置一个数据模板,然后只使用contentcontrol,这更像是“自动”。您的模型使用的是
observeCollection
(增加通知),但您没有为例如
ModelB.Make
ModelB.Cs
ModelC.Brand
更改等实现任何类型的通知。因此,从技术上讲,显示它们不是MVVM。通常,模型必须提供通知ViewModel的机制(
INotifyPropertyChanged
很好),虽然ViewModels几乎
必须
实现
INotifyPropertyChanged
。可能更容易的方法是使
ModelB
/
ModelC
实现
INotifyPropertyChanged
,但它们实际上变成了ViewModels,可以直接用于绑定。有关绑定到未实现的对象的原因,请参阅e> INotifyPropertyChanged
正在工作。TLDR;对模型所做的更改只有在视图本身进行更改时才能在视图中看到。@Sinatr不发出通知并不意味着“它不是MVVM”。
public class ModelBViewModel
{
    private ModelB _model;

    public ObservableCollection<ModelCViewModel> CVms { get; set; }

    public ModelBViewModel(ModelB model) {
        _model = model;
        CVms = new ObservableCollection();
        foreach(var modelC in model.Cs) {
            CVms.Add(new ModelCViewModel(modelC));
        }
    }
}