为什么在viewmodel上实现接口并在mvvm中查看

时间:2012-07-13 02:44:02

标签: wpf silverlight mvvm prism

我对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.)如果这是一种可接受的实现方式,我是否需要为所有模块中的所有视图和视图模型提供接口。

2 个答案:

答案 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注入视图

这意味着ViewModel不再具有对View的任何后向引用。这意味着在对ViewModel进行单元测试时,您不需要模拟视图。此外,它使代码更清晰,因为在View的构造函数中,它只是将DataContext设置为注入的ViewModel。

  • 向ViewModels注入视图。

它避免将工作流逻辑保留在Presentation层中。这意味着Application层负责应用程序工作流。 这样,工作流逻辑与视图高度耦合,因此很难为此编写单元测试。