c# - C# MVVM 模式下的 Modal Popup 和 View 通信

标签 c# wpf mvvm caliburn.micro modalpopup

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

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

到目前为止,我发现的唯一可能的替代方法是使用 ModalContentPresenter来自 this blog 的类(class).这个解决方案的问题是:

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

  • 我想使用模态弹出窗口的一些例子是:
  • 在 View 上放置一个按钮以选择客户端。它应该打开一个包含所有可能客户端的弹出窗口并让用户选择一个。
  • 将产品弹出窗口添加到客户订单。

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

    最佳答案

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

    I need to write the father view XAML and modal XAML on the same view.



    你实际上可以写两个在单独的文件中查看。然后可以使用 DataTemplates 动态加载 View 。这将取决于 ViewModel绑定(bind)到 ContentModalContent特性。

    this它描述了可以实现这种 View 切换的一般方式。

    你可以有一个 MainViewModel它有两个属性,PrimaryViewModelSecondaryViewModel它返回适当的 View 模型,为主要和模态内容提供属性和命令。

    您可以在 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属性(property)给 true ModalContentPresenter将显示您的 SecondaryView .

    I cannot have multiple popus from same view.



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

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

    Some example on where i'd like to use modal popups is:

    Put a button on a view to select a Client. It should open a popup with all possible clients and let the user chose one.

    Add a product popup to a customer order.



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

    例如,考虑具有以下接口(interface)的 View 模型:
    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>
    

    以下是它的工作原理:
  • IsSelectingCustomer MainViewModel 的属性(property)将以 false 开始.
  • 单击主视图中的按钮将调用 SelectCustomerCommand目的。然后该命令将告诉 MainViewModel更改IsSelectingCustomer属性(property)给 true .
  • ModalContentPresenter将显示由数据模板指定的 View 。用户现在只能与“选择客户 View ”进行交互。
  • 选择客户后,可以单击一个按钮(绑定(bind)到 CustomerSelectedCommandSelectCustomerViewModel),这反过来会引发 CustomerSelected事件。
  • MainViewModel会有一个事件处理程序来响应 CustomerSelected事件。然后处理程序将读取 SelectedCustomer来自 SelectCustomerViewModel 的属性(property)最后,它将设置 IsSelectingCustomer属性返回 false,导致模态内容关闭。
  • 关于c# - C# MVVM 模式下的 Modal Popup 和 View 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25815711/

    相关文章:

    C# HttpWebRequest - 转义 POST 内容?

    c# - 相对于中心而不是左上角缩放 WPF Canvas

    c# - 包含两个 Caliburn.Micro View 的对话框 View ?

    具有可变数量的按钮/形状的 WPF DataGrid 列

    c# - 在 WPF 中绑定(bind)源时图像未显示

    C# Nhibernate 保存列表

    wpf - IDataErrorInfo 与 ValidationRule 与异常

    c# - MVVM 设置 MenuItem 的 DataContext

    c# - 如何在另一个窗体窗体中显示图形

    wpf - 如何在 ControlTemplate 中使用 ElementName 绑定(bind)?