MVVM,对ViewModelLocator和DataTemplate感到困惑,首先导致ViewFirst vs ViewModel

时间:2014-12-23 17:26:28

标签: c# wpf mvvm mvvm-light

我使用MVVMLight,它附带一个ViewModelLocator。

我的初始项目提出了以下问题。我有一个MainView,在说明应用程序时呈现。根据单击的按钮,它通过MainView中的ContentControl呈现View1或View2(每个都是用户控件)。

我在MainViewModel中找到了正确的视图模型。但我发现我还需要一个DataTemplate,以便View1和View2中的用户控件将在MainView中正确呈现,否则它只会显示基于文本的类名。

我对以下内容感到困惑:

a)我是否需要两者,一个视图模型定位器和一个DataTemplate来完成上述操作?我刚跳进WPF,但我以为我读过一个或另一个不是两个都需要。或者更具体:为什么我的视图中有DataContext="{Binding LiveDataViewModel, Source={StaticResource Locator}}">(它解析了对自己的视图模型的绑定)但仍需要DataTemplate?

b)这是视图模型的第一种方法还是视图第一种方法?

c)我尝试了一个代码隐藏的解决方案,它实际上花了我4行代码来完成同样的事情,带走了我很多课程,绕路,eventToCommand&转换器[因为触发选择视图的控件只引发事件而不是命令],数据模板,视图模型定位器,不同的视图模型......这看起来是一笔巨大的成本,无论如何都没有优势。把它放到代码背后似乎很完美,因为它是纯UI内容(选择视图并绑定到内容控件,完成)。我在这里错过了什么吗?我会通过代码放弃什么?

我是WPF和MVVM的新手,现在我感到非常沮丧,因为我觉得我围绕一个看似微不足道的问题跑圈子。

1 个答案:

答案 0 :(得分:4)

如果这个答案听起来很基本,我很抱歉,但听起来你可能仍然在学习WPF并误解了一些关键的事情。

首先,WPF应用程序有两层:

  • 由您在屏幕上呈现的对象组成的UI图层
  • 和位于UI后面的数据层,称为DataContext

进行绑定时,您将从数据层提取数据并将其放入UI层。

ViewModelLocator影响数据层。它用于查找放置在UI对象后面的适当数据对象。

现在,在数据对象直接插入UI层的情况下,例如直接绑定到数据层的.Content.ItemsSource属性的任何内容,WPF将呈现数据的默认方式object是使用TextBlock显示对象的.ToString()

您可以覆盖它并告诉WPF如何使用DataTemplate绘制任何类型的对象。您可以告诉控件使用特定模板进行渲染,也可以告诉WPF使用特定的DataTemplate自动渲染X类型UI层中的任何对象。

所以回答你的问题

  

a)我是否需要两者,一个视图模型定位器和一个DataTemplate来完成上述操作?或者更具体:为什么我的视图中有DataContext="{Binding LiveDataViewModel, Source={StaticResource Locator}}">但仍需要DataTemplate?

这是两个单独的项目。 ViewModelLocator定位UI对象后面的数据项,DataTemplate告诉WPF如何绘制该项。

您的绑定是说“将数据层(DataContext)绑定到Locator.LiveDataViewModel”,我的最佳猜测是XAML中的某些内容直接绑定ItemsSourceContent使用像Content="{Binding }"

这样的XAML到数据层
  

b)这是视图模型的第一种方法还是视图第一种方法?

我认为无论何时使用ViewModelLocator,它都是一种视图优先方法,因为View负责从Locator获取数据项。在View调用之前,数据不存在。

就我个人而言,我从不使用ViewModelLocator,因为我不喜欢它有的限制,并且更喜欢模型优先的方法,但这并不意味着你不能使用它。如果你想要的话。 p>

  

c)我尝试了一个代码隐藏的解决方案,它实际上花了我4行代码来完成同样的事情,带走了我很多课程,绕路,eventToCommand&转换器[因为触发选择视图的控件只引发事件而不是命令],数据模板,视图模型定位器,不同的视图模型......这看起来是一笔巨大的成本,无论如何都没有优势。把它放到代码背后似乎很完美,因为它是纯UI内容(选择视图并绑定到内容控件,完成)。我在这里错过了什么吗?我会通过代码放弃什么?

我不知道你的代码是什么样子,但听起来好像有很多不必要的代码。 MVVM模式背后的想法是让所有应用程序逻辑都驻留在类中,并且所有用户界面逻辑都驻留在UI控件中。由于其绑定系统,WPF非常适合这种设计。

这样可以轻松地将备用用户界面连接到您的应用程序,最常见的用户界面是测试脚本。它还具有将UI与业务逻辑完全分离的优势,这在与专用UI团队合作时是一个巨大的帮助。

我个人使用MVVM来处理每个WPF应用程序,甚至是非常简单的应用程序。我可能会在简单的应用程序中模糊一些规则,但是当MVVM选项存在时,我永远无法回到构建应用程序的旧WinForms风格。

如果您有兴趣,我已经为WPF初学者撰写了一些博客文章,如果您刚开始使用它们可能会有用:

希望这会有所帮助,祝你好运:)。