我对MVVM模式很新,所以请耐心等待。我已经看到了wpf + mvvm + prism中的实现,其中所有视图都倾向于将IView作为最顶层的接口。然后,各个模块中的视图具有视图特定的接口,如IViewA,IViewB等,它们实现了IView接口。甚至视图模型也具有IViewModel最顶层接口,后续模块具有从IViewmodel继承的IViewAViewModel,IViewBViewModel等。 IViewmodel引用了Iview,Iview引用了IViewModel。
namespace xxx.xxx.infrastructure
{
public interface IView
{
IViewModel ViewModel {get;set;}
}
public interface IViewModel
{
IView View {get;set;}
}
public abstract class ViewModelBase : IViewModel, INotifyPropertyChanged
{
public IView View {get;set;}
public ViewModelBase(IView view)
{
View = view;
View.ViewModel = this;
}
//INotifyPropertyChanged left out
}
}
namespace xxx.xxx.Modules.Customer
{
public interface ICustomerDetailsView : IView
{
}
public partial Class CustomerDetailsView : UserControl, ICustomerDetailsView
{
public CustomerDetailsView ()
{
InitializeComponent();
}
//Is this implementation acceptable?The view is supposed to have zero code in the code behind.....
public IViewModel ViewModel
{
get
{
return (ICustomerDetailsViewViewModel)DataContext;
}
set
{
DataContext = value;
}
}
}
public interface ICustomerDetailsViewViewModel : IViewModel
{
string Message {get;set;}
}
public class CustomerDetailsViewViewModel : ViewModelBase, ICustomerDetailsViewViewModel
{
//Will be injected by unity as i have set up mappings in module initilize.
public CustomerDetailsViewViewModel(ICustomerDetailsView view)
:base(view)
{
}
public string Message
{
//INotifyPropertyChanged left out for brevity
get;set;
}
}
我有几个问题。
1.)作为代码隐藏文件的MVVM是否应该没有代码?
2.)在MVVM视图模型中不应该担心视图或其合约吗?上述实现是否会破坏它?3.)我无法理解这种实现的用途。事实上,这与MVP接壤,需要大量代码。
4.)如果这是一种可接受的实现方式,我是否需要为所有模块中的所有视图和视图模型提供接口。
答案 0 :(得分:12)
首先是Rachel关于viewmodel的一个非常好的评论:
请记住,使用MVVM,您的ViewModel就是您的应用程序。观点是 只是一个漂亮的界面,允许用户与您的互动 的ViewModels。
1)IView对我来说违反了MVVM,但是当然允许代码隐藏用于ui的东西。 viewmodel应该没有对视图的引用。参见Hasith的第一条评论
2)看我的blockquote
3)我和你在一起 - 我从来没有在我的项目中使用类似的东西
4)请轻松做MVVM - 没有耦合,使用di,ioc,命令,行为,对我来说最重要的是:viewmodel first :)答案 1 :(得分:7)
基本上,我们只需要注射接口。有两种方式:
这意味着ViewModel不再具有对View的任何后向引用。这意味着在对ViewModel进行单元测试时,您不需要模拟视图。此外,它使代码更清晰,因为在View的构造函数中,它只是将DataContext设置为注入的ViewModel。
它避免将工作流逻辑保留在Presentation层中。这意味着Application层负责应用程序工作流。 这样,工作流逻辑与视图高度耦合,因此很难为此编写单元测试。