让 XAML 按钮为视图发送一条消息,为 VM (MVVM) 发送一条消息是否正确?

Is right to have a XAML button send one message for the View and one for the VM (MVVM)?

我正在为 WP 8.1 开发一个简单的联系人管理器。 MV 是已添加联系人的列表,并有一个用于创建新联系人的按钮(新联系人视图 - NCV)。 NVC 视图有一个保存按钮,我将此按钮用于两个建议:

  1. 将新联系人添加到联系人列表中,这发生在 VM
  2. 发送事件到代码隐藏文件离开视图返回到主视图 查看。

有效!有了这个,我避免了 VM 必须向视图发送事件消息。

但这是错误的吗?

如果错了,有什么简单的方法可以避免吗?

有魔法线:

<Button Content="Save" Command="{Binding AddNewContactCommand}" Click="Button_Click" />

您的问题是基于意见的,因此您可能会得到截然不同的答案。您的评论说 "No, don't do that because you'll break the MVVM pattern",但这取决于项目的规模、寿命和专业水平以及您的总体编程风格。事实上,在 MVVM 中使用视图相关逻辑的代码隐藏是完全正确的,尽管我敢肯定一些顽固的 MVVM 开发人员会不同意这种说法。

但是,如果您不想使用隐藏的代码,还有其他方法可以从视图模型加载视图,您可以在 WPF MVVM navigate views 问题中找到一个常见的方法。这里要展示的东西太多了,但总体思路是这样的:

您的所有视图模型都应扩展一个抽象基础 class,我们称它为 BaseViewModel

public BaseViewModel ViewModel { get; set; }

在 App.xaml 中,您可以声明一些简单的 DataTemplates 以将视图与视图模型连接起来:

<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
    <Views:MainView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:PersonViewModel}">
    <Views:PersonView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:CompanyViewModel}">
    <Views:CompanyView />
</DataTemplate>

现在,无论您在应用程序中使用哪个 BaseViewModel 实例,这些 DataTemplate 都会告诉框架显示相关视图。您可以这样显示它们:

<ContentControl Content="{Binding ViewModel}" />

要切换到新视图,只需在 MainViewModel class:

中设置 ViewModel 属性
ViewModel = new PersonViewModel();

有关此方法的更多信息,请参阅链接问题。

当然,一旦您实施了这个系统,您可能会想 'How can I change the view model in the main view model from a child view model?' 可以在 How to call functions in a main view model from other view models? 问题中找到答案。