C# 带有视图模型的 MVVM 继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/977652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVVM Inheritance With View Models
提问by Richard McGuire
I am wondering about how to approach inheritance with View Models in the MVVM pattern. In my application I have a Data Model that resembles the following:
我想知道如何在 MVVM 模式中使用视图模型来处理继承。在我的应用程序中,我有一个类似于以下内容的数据模型:
class CustomObject
{
public string Title { get; set; }
}
class CustomItem : CustomObject
{
public string Description { get; set; }
}
class CustomProduct : CustomItem
{
public double Price { get; set; }
}
In my application I have a ViewModelBase class and then was going to have the following View Models:
在我的应用程序中,我有一个 ViewModelBase 类,然后将有以下视图模型:
- CustomObjectViewModel
- CustomItemViewModel
- CustomProductViewModel
- 自定义对象视图模型
- 自定义项视图模型
- 自定义产品视图模型
A rough implementation of the CustomObjectViewModel would resemble the following:
CustomObjectViewModel 的粗略实现类似于以下内容:
class CustomObjectViewModel : ViewModelBase
{
private readonly CustomObject _customObject;
public CustomObjectViewModel( CustomObject customObject )
{
_customObject = customObject;
}
public string Title
{
// implementation excluded for brevity
}
}
It seems logical to me that my View Models would extend themselves in the same manner as my Model did (CustomItemViewModel extends CustomObjectViewModel and so on). However, I have noticed that as I go down the inheritance tree I'll be adding additional references to the same object. This seems rather excessive to me and was wondering how to approach this problem and if it were possible to make it much cleaner.
在我看来,我的视图模型会以与我的模型相同的方式扩展自己(CustomItemViewModel 扩展 CustomObjectViewModel 等等),这似乎是合乎逻辑的。但是,我注意到当我沿着继承树向下走时,我将添加对同一对象的其他引用。这对我来说似乎有些过分,并且想知道如何解决这个问题以及是否有可能使它更干净。
采纳答案by Enrico Campidoglio
Generally I would recommend you not to have inheritance between different ViewModel classes, but instead having them inherit directly from a common abstract base class.
This is to avoid introducing unnecessary complexity by polluting the ViewModel classes' interfaceswith members that come from higher up in the hierarchy, but are not fully cohesiveto the class's main purpose.
The coupling that comes with inheritance will also likely make it hard to change a ViewModel class without affecting any of its derived classes.
If your ViewModel classes always will reference a single Model object, you could use generics to encapsulate this rule into the base class:
通常,我建议您不要在不同的 ViewModel 类之间进行继承,而是让它们直接从公共抽象基类继承。
这是为了避免引入不必要的复杂性,因为来自层次结构中较高级别但与类的主要目的不完全一致的成员污染了 ViewModel 类的接口。继承带来的耦合也可能使更改 ViewModel 类而不影响其任何派生类变得困难。
如果您的 ViewModel 类总是引用单个 Model 对象,您可以使用泛型将此规则封装到基类中:
public abstract class ViewModelBase<TModel>
{
private readonly TModel _dataObject;
public CustomObjectViewModel(TModel dataObject)
{
_dataObject = dataObject;
}
protected TModel DataObject { get; }
}
public class CustomObjectViewModel : ViewModelBase<CustomObject>
{
public string Title
{
// implementation excluded for brevity
}
}
public class CustomItemViewModel : ViewModelBase<CustomItem>
{
public string Title
{
// implementation excluded for brevity
}
public string Description
{
// implementation excluded for brevity
}
}
回答by Martin Harris
I'd be interested to see if there is a better answer for this, but when I have had the same problem I've always enclosed an explicit cast of the object as a private property like so:
我很想知道是否有更好的答案,但是当我遇到同样的问题时,我总是将对象的显式转换包含为私有属性,如下所示:
class CustomObjectViewModel : ViewModelBase
{
protected readonly CustomObject CustomObject;
public CustomObjectViewModel( CustomObject customObject )
{
CustomObject = customObject;
}
public string Title
{
// implementation excluded for brevity
}
}
class CustomItemViewModel : CustomObjectViewModel
{
protected CustomItem CustomItem { get { return (CustomItem)CustomObject; } }
public CustomItemViewModel( CustomItem customItem )
:base(customItem)
{
}
}
It works, and it's the best I've come up with, but has never felt very clean to me.
它有效,这是我想出的最好的,但我从来没有觉得很干净。
回答by Jose
Related to the comment above of Enrico. ViewModels should not be tightly coupled with views, it should be the other way around. Views should be loosely coupled to ViewModels. A ViewModel should not know about a view, this allows you to unit test a ViewModel easily.All interactions between Views with the ViewModel should be implemented via properties in the ViewModel(ICommand properties for actions and other properties for databinding).
与以上 Enrico 的评论相关。ViewModel 不应该与视图紧密耦合,而应该相反。视图应该与视图模型松散耦合。ViewModel 不应该知道视图,这允许您轻松地对 ViewModel 进行单元测试。 Views 与 ViewModel 之间的所有交互都应通过 ViewModel 中的属性(用于操作的 ICommand 属性和用于数据绑定的其他属性)实现。
The one thing that is true is that the ViewModel is tightly coupled with the Model, so the use of generics above allows alot of extensibility. It is the pattern that I would recommend.
有一点是正确的,ViewModel 与 Model 紧密耦合,因此上面泛型的使用允许很多可扩展性。这是我推荐的模式。
By providing a ViewModel class that basically just exposes Properties it should allow you to plop that into any kind of presentation framework and leverage all the code you've used previously. In other words, if properly implemented you could drop your ViewModels assembly into a ASP.NET MVC app and tie the view to the properties and have no code change.
通过提供一个基本上只公开 Properties 的 ViewModel 类,它应该允许您将其放入任何类型的表示框架并利用您以前使用过的所有代码。换句话说,如果正确实现,您可以将 ViewModels 程序集放入 ASP.NET MVC 应用程序并将视图绑定到属性,而无需更改代码。
A good article on MVVM basics is : this one.I really think that MVVM is the best thing out there for UI development. Obviously we can't all use it because it requires building an app from the ground up using the MVVM approach, but when you're building a new app that is not an issue.
一篇关于 MVVM 基础知识的好文章是:this one。我真的认为 MVVM 是 UI 开发的最佳选择。显然我们不能全部使用它,因为它需要使用 MVVM 方法从头开始构建应用程序,但是当您构建新应用程序时,这不是问题。
The one gripe I have with ICommand is that it is in the PresentationCore Assembly which is basically for WPF. If Microsoft wanted loose coupling it should be in another assembly altogether.
我对 ICommand 的一个抱怨是它位于基本上用于 WPF 的 PresentationCore 程序集中。如果微软想要松耦合,它应该完全在另一个程序集中。
回答by Cameron MacFarland
I think the issue here is that there should be one ViewModel for each View, and not one ViewModel for each model.
我认为这里的问题是每个视图都应该有一个 ViewModel,而不是每个模型都有一个 ViewModel。
The reason for this is fairly obvious, as you can only set one object to be the DataContext, that object should be the ViewModel for that View.
这样做的原因很明显,因为您只能将一个对象设置为 DataContext,该对象应该是该视图的 ViewModel。