1

我有一个用 VB6 编码的大型项目,几个月来我一直在尝试升级到新技术。我的项目包含 6 个管理模块,它们在客户端-服务器应用程序下重新组合。来自 VB,我合乎逻辑的选择是升级到 .NET。经过大量研究后,我决定使用C#,WPF和 MVVM 模式(使用 Caliburn Micro)。

一开始我遇到了一些问题,但我设法解决了它们。但是现在我已经到了需要(就像每个复杂的应用程序一样)通过模态弹出窗口(或其他一些技术)与不同的视图及其对应的 viewModel 进行通信的地步。在这件事上,MVVM 模式似乎非常严格或复杂。一个简单的“您确定要删除此记录吗(是/否)”是一项非常复杂的任务。因此,我正在寻找有关如何在没有复杂工件的情况下作为 EventAgregators 交流视图的建议。

到目前为止,我发现的唯一可能的替代方法是使用该博客ModalContentPresenter中的类。这个解决方案的问题是:

  • 我需要在同一个视图上编写父视图 XAML 和模态 XAML。
  • 我不能从同一个视图中获得多个 popus。

我想使用模态弹出窗口的一些例子是:

  • 在视图上放置一个按钮以选择客户端。它应该打开一个包含所有可能客户端的弹出窗口并让用户选择一个。
  • 将产品弹出窗口添加到客户订单。

有什么想法或建议吗?一些示例代码将不胜感激?谢谢!

4

1 回答 1

1

我是链接ModalContentPresenter控件的作者,因此我将尝试解决您的一些问题和疑虑。

我需要在同一个视图上编写父视图 XAML 和模态 XAML。

您实际上可以将两个视图写入单独的文件中。然后可以动态加载视图DataTemplates,这取决于ViewModel绑定到ContentModalContent属性的 。

请参阅this,它描述了可以实现此视图切换的一般方式。

你可以有一个MainViewModelwhich 有两个属性,PrimaryViewModelSecondaryViewModel返回适当的视图模型,这些模型为主要和模态内容提供属性和命令。

您可以在以下设置XAML

<DataTemplate DataType="{x:Type FooViewModel}">
    <Controls:FooView />
</DataTemplate>

<DataTemplate DataType="{x:Type BarViewModel}">
    <Controls:BarView />
</DataTemplate>

<controls:ModalContentPresenter 
              Name="modalPresenter"
              Content={Binding DataContext.PrimaryViewModel}
              ModalContent={Binding DataContext.SecondaryViewModel} />

IsModal属性为false时,只会PrimaryView显示您的。只要您将IsModal属性设置为trueModalContentPresenter就会显示您的SecondaryView.

我不能从同一个视图中获得多个 popus。

我认为您的意思是您希望能够从同一主视图在不同时间显示不同的模态内容。

使用上述技术,这就像切换ViewModel绑定到ModalContent属性的 (在显示它之前通过设置IsModaltrue)一样简单。只要您有一个绑定的DataTemplatefor ViewModel(并且您的MainViewModel实现INotifyPropertyChanged正确),就会显示正确的内容。

我想在哪里使用模态弹出窗口的一些例子是:

在视图上放置一个按钮以选择客户端。它应该打开一个包含所有可能客户端的弹出窗口并让用户选择一个。

将产品弹出窗口添加到客户订单。

一旦你理解了上面描述的技术,你应该能够看到,只要你有一个ViewViewModel对,你就可以涵盖你能想到的任何场景。

例如,考虑具有以下接口的视图模型:

public interface SelectCustomerViewModel : INotifyPropertyChanged {
    event EventHandler CustomerSelected;        
    public ObservableCollection<Customer> Customers { get; }
    public Customer Customer { get; set; }
    public Command CustomerSelectedCommand { get; }
}

public interface MainViewModel : INotifyPropertyChanged {
    public SelectCustomerViewModel ModalContent { get; }
    public Command SelectCustomerCommand { get; }
    public bool IsSelectingCustomer { get; }
}

你可以XAML看起来像这样:

<Window x:Class="ModalContentTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Select a customer">

    <DataContext>
        <vm:MainViewModel />
    </DataContext>

    <DataTemplate DataType="{x:Type SelectCustomerViewModel}">
        <Controls:SelectCustomerView />
    </DataTemplate>

    <c:ModalContentPresenter Name="modalPresenter"
                             ModalContent={Binding ModalContent}
                             IsModal={Binding IsSelectingCustomer}>

        <!-- This is the primary content! -->
        <Grid>
            <Button Content="Select a customer"
                    Command={Binding SelectCustomerCommand} />
        </Grid>

    </c:ModalContentPresenter>

</Window>

以下是它的工作原理:

  1. IsSelectingCustomer属性以MainViewModel开始false
  2. 单击主视图中的按钮将调用该SelectCustomerCommand对象。然后该命令将告诉 将属性MainViewModel更改为。IsSelectingCustomertrue
  3. ModalContentPresenter显示由数据模板指定的视图。用户现在只能与“选择客户视图”进行交互。
  4. 选择客户后,可以单击按钮(绑定到 的CustomerSelectedCommandSelectCustomerViewModel,这反过来会引发CustomerSelected事件。
  5. MainViewModel有一个事件处理程序来响应CustomerSelected事件。然后,处理程序将从 中读取SelectedCustomer属性SelectCustomerViewModel,最后将IsSelectingCustomer属性设置回 false,从而关闭模态内容。
于 2014-09-13T08:11:43.267 回答