在MVVM中实现Visual Inheritance的策略是什么?

时间:2010-08-03 13:41:14

标签: c# wpf mvvm

我想在我的框架上用MVVM模式编写一个Detail(Info)屏幕。将有一个基本详细信息视图模型和视图,在此工具栏上有一个工具栏和按钮(保存,删除,新按钮等)。此框架的用户可以在不使用手动添加的工具栏的情况下编写他/她的详细信息(信息)屏幕。他们的详细信息(信息)屏幕的视图模型将继承自框架的详细信息(info)视图模型。因此工具栏会自动添加到他/她的详细信息屏幕中。

之前是否有人实施过这样的情况,或者您可以就此问题给我一个模式或策略吗?谢谢大家。

3 个答案:

答案 0 :(得分:2)

我不使用视觉继承。相反,我有主窗口,按钮工具栏和插入用户控件的区域。

每个用户控件实现界面的ViewModels都有工具栏上的按钮命令,因此我可以将按钮绑定到每个用户控件中的命令实现。

请参阅此MSDN文章中的示例:WPF Apps With The Model-View-ViewModel Design Pattern

答案 1 :(得分:1)

我的MVVM中没有可视继承 - 我设计我的程序以适应平台而不是明确使用不支持的技术。

我将公共元素构建为视图使用的控件,或者作为从框架中自动插入的Decorator或ContentControl派生的类(在这种情况下,视图将成为该控件的子级)。

即使您找到了一些可以让您使用视觉继承的解决方法,但它不受支持,并且当您遇到解决方法的限制时,这是一种可靠的方法来解决问题

答案 2 :(得分:1)

我认为“继承”不适合你在这种情况下使用,虽然我不知道是什么。

“继承”意味着类和子类之间的特定关系。您可以构建视图模型基类并从中继承,但是您无法通过视图真正有意义地执行此操作,因为视图是通过合成而不是通过实现属性和方法来构建的。

但是,构建一个可以执行所描述的视图模型基类当然是有意义的。我现在在我正在进行的项目中这样做。我有一个视图模型类,它通过公开CommandLinks集合来支持菜单中的链接。集合中的每个CommandLink对象都会公开链接文本,更详细的描述和Command。在视图中,我有DataTemplateHyperlink内列出TextBlockDockPanel,视图模型的DataTemplate包含{ {1}}绑定到视图模型中的ItemsControl集合。视图模型子类填充其CommandLinks集合,Bob是您的叔叔。我的应用程序不需要填充基类中的CommandLinks集合,因为每个视图模型类的命令都不同,但我没有理由不这样做。

但是,我不会称之为“视觉继承”。因为如果我决定以不同的方式布置特定的视图模型类,我不能在我的实现中覆盖CommandLinks。我必须专门为该类构建一个新的DataTemplate。这是继承概念开始崩溃的地方。

如果我将DataTemplate(例如)的DataContext设置为我的视图模型的实例,WPF将查看资源字典以查找由对象类型键入的ContentPresenter 。如果派生类型没有定义,则它将使用基类型的模板。但是如果派生类型 有一个定义,WPF将使用该类型。而且你真的没有办法从另一个模板继承一个模板,所以子类的模板不能神奇地看起来像基类的模板。

你最终会像这样实现它:

DataTemplate

这不是真正的继承。没有修改基类的数据模板,没有人可以实现自己的派生类。

通过为容器模板提供密钥,您可以解决这个问题。但是实现该视图的人需要了解这一点。他不能这样做,例如:

<DataTemplate DataType="{x:Type MyBaseClass}">

   <DataTemplate.Resources>
       <DataTemplate DataType="{x:Type MyBaseClass}"> ...
       <DataTemplate DataType="{x:Type MyDerivedClass1}"> ...
       <DataTemplate DataType="{x:Type MyDerivedClass2}"> ...
   </DataTemplate.Resources>

   <DockPanel>
      <ItemsControl DockPanel.Dock="Left" ItemsSource="{Binding CommandLinks}"/>
      <ContentPresenter DataContext="{Binding}"/>
   </DockPanel>

</DataTemplate>

但是必须做类似的事情:

<ItemsControl ItemsSource="{Binding MyObjectList}"/>

对我而言,这似乎不是一个巨大的代价。但后来我通常是我项目中唯一的开发人员。