【发布时间】:2012-07-12 21:20:18
【问题描述】:
我对 MVVM 模式很陌生,所以请多多包涵。我在 wpf +mvvm + prism 中看到了实现,其中所有视图都倾向于将 IView 作为最顶层的界面。然后各个模块中的视图有一个视图特定的接口,如 IViewA、IViewB 等,它们实现了 IView 接口。甚至 viewmodel 也有 IViewModel 最顶层的接口,并且后续模块有 IViewAViewModel 、 IViewBViewModel 等继承自 IViewmodel。 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.)如果这是一种可接受的实现方式,我是否需要为所有模块中的所有视图和视图模型提供接口?
【问题讨论】:
-
我与 WPF 的合作不多,但我同意您作为设计实践的观点。 VM 不应该引用视图,我认为不需要它,除非您没有正确使用双向绑定。关于无处不在的接口......这是静态语言的不幸事实,其中合约需要采用接口的形式。 Unity 应该为它的 DI 东西提供苛刻的接口..
-
@Hasith 其实并不是视图的具体实现,只是视图的一个接口。我可以说这仍然满足 MVVM,因为 VM 不知道实现 IView 的窗口/页面
-
是的,但是视图模型仍然需要了解视图的契约。这意味着比与独立 ViewModel 更多的耦合。为什么在双向绑定到位时需要它?想象一下,当您需要多个视图来共享同一个视图模型时(例如,在同一个窗口中紧密相关的多个 UI 组件)。不知道它在 WPF 中是如何工作的,但我已将其用作 Javascript MVVM 框架中的强大实践。
-
“视图模型”不是模型;它更像是一个“控制器”或“演示者”,将视图与真实模型分离。当然,真实模型是可选的,在许多情况下,VM 充当模型......
-
@Hasith:完全同意你的观点,不需要在 ViewModel 中注入任何 IView。 MVVM 基于 Presentation Model 模式,所以 View 担心与 View(Presentation)Model 同步状态。 ViewModel 只需要引发它状态已更改的事件,并且 View 将同步(通过事件订阅或绑定)。如果 IView 注入 ViewModel,则意味着 ViewModel 担心与它 View 同步状态,看起来像 MVP Supervising Controller。
标签: wpf silverlight mvvm prism