MVVM传递数据给对话框视图模型

15

我正在研究使用MVVM,虽然我大部分都理解了,但有一件事情我无法理解。

假设我有一个View和ViewModel的组合,显示一个foobars列表。当用户选择列表中的一个foobar并点击编辑按钮时,我希望它会在弹出的对话框窗口中显示,以便进行编辑。这个对话框窗口(即视图)将有自己关联的ViewModel。

我知道可以将按钮绑定到列表ViewModel上的命令,但从这里开始,如何实例化foobar编辑器呢?

1)我是否必须发送消息回到View,以打开对话框窗口?如果是这样,这不会让命令失去意义吗?

2)foobar是如何传递到编辑器ViewModel中的?如果是通过构造函数,这不会使在XAML中声明ViewModel变得困难吗?

我认为这是阻止我使用MVVM的最后一块拼图,我真的很想得到一个好的解耦解决方案。

谢谢 Matt

3个回答

2
我会按以下方式进行:
  1. 附加到编辑按钮的命令启动编辑对话框,并为其创建自定义 ViewModel(VM)。该命令本身应该放在列表的 VM 或 Model 中(不太确定)。
  2. Foobar 编辑对话框的 VM 在其构造函数中获取对 Foobar 的引用。
  3. Foobar 被克隆并进行编辑。
  4. 一旦用户在 foobar 编辑对话框中按下“确定”按钮,副本的值就会被写回到 VM 中的原始 foobar 中(并关闭对话框)。
所需克隆的原因是用户不希望在接受编辑对话框中的更改之前在 foobar 列表中看到更改。但是,如果在线编辑可以,请不需要克隆。
更改会自动传播。
PS:虽然我是 MVVM 的支持者,但我不确定我的解决方案从纯 MVVM 角度来看是否是正统的。

1

这篇文章来自CodeProject,展示了一个WPF对话框控件,恰好符合您的需求。这种实现的原因是你不能把一个窗口放在任何其他控件的可视树中。也就是说,开箱即用的WPF不允许你在窗口内创建对话框。所以上述文章创建了一个子类ContentControl,它创建了一个窗口。

总之,你可以把它放在你的FooBarList视图里。

<dialog:Dialog Content="{Binding Path=DialogViewModel}" /> 

请确保您在资源字典中有类似以下内容的条目:

<Style TargetType="{x:Type dialog:Dialog}">
 <Style.Triggers>
  <Trigger Property="HasContent" Value="True">
   <Setter Property="Showing" Value="True" />
  </Trigger>
 </Style.Triggers>
</Style>

只需要像这样写(为了使 WPF 工作,您需要实现 INotifyPropertyChanged 接口):

public Class FooBarListViewModel
{
  IList<FooBar> FooBarList {get;set;}
  FooBar SelectedFooBar {get;set;}
  ViewModelBase DialogViewModel {get;set;}

  public EditFooBar(object param)
  {
    DialogViewModel = FooBar;
  }
}

要将视图链接到编辑FooBar的FooBar ViewModel,只需像这样做(最好在Application.Resources中,这样它就是全局的)

<DataTemplate DataType={x:Type vm:FooBarViewModel}>
  <vw:FooBarView/>
</DataTemplate>

(或者选择:使用IValueConverter将ViewModel转换为View,就像这篇文章所展示的那样

然后你就可以开始了。听起来可能有点麻烦,但它确实能够大大解放你。


这是一个有趣的方法。看了一下示例项目,我在想是否会失去一些普通窗口的功能(调整大小、非模态等)而受到影响。我开始认为,也许值得考虑设计一个根本不需要复杂对话框的方案,而是使用 MDI 应用程序。你对此有什么想法? - Matt

0
缺少的是控制器,它负责ViewModel的工作流程。控制器创建ViewModel并在ViewModel之间传递必要的数据。 WPF应用程序框架(WAF)项目包含展示这种工作方式的示例应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接