我有一个用VB6编码的大型项目,我已经尝试升级到几个月的新技术。我的项目包括在客户端 - 服务器应用程序下重新组合的6个管理模块。来自VB,我的逻辑选择是升级到.NET。经过大量研究后,我决定使用C#
,WPF
和MVVM模式(使用Caliburn Micro)。
在开始时我遇到了一些问题,但我设法解决了这些问题。但是现在我已经到了需要(像每个复杂的应用程序)通过模态弹出窗口(或其他一些技术)与不同视图及其相应的viewModel进行通信的点。在这个问题上,MVVM模式似乎非常严格或复杂。一个简单的"您确定要删除此记录(是/否)"是一项非常复杂的任务。因此,我正在寻找建议,因为如何在没有复杂工件的情况下传达视图作为EventAgregators。
到目前为止,我发现唯一可行的替代方法是使用this blog中的ModalContentPresenter
类。这个解决方案的问题是:
我想要使用模态弹出窗口的一些示例是:
有任何想法或建议吗?一些示例代码将不胜感激?谢谢!
答案 0 :(得分:1)
我是关联ModalContentPresenter
控件的作者,因此我将尝试解决您的一些问题和疑虑。
我需要在同一视图上编写父视图XAML和模态XAML。
您实际上可以在单独的文件中编写两个视图。然后可以使用DataTemplates
动态加载视图,这取决于绑定到ViewModel
或Content
属性的ModalContent
。
参见this,其中描述了可以实现此视图切换的一般方式。
您可以拥有一个MainViewModel
,它有两个属性PrimaryViewModel
和SecondaryViewModel
,它们会返回适当的视图模型,这些模型提供主要内容和模态内容的属性和命令。
您可以在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
属性设置为true
,ModalContentPresenter
就会显示您的SecondaryView
。
我不能从同一视图中获得多个popus。
我认为你的意思是希望能够在同一主视图中显示不同时间的不同模态内容。
使用上述技术,这就像切换绑定到ViewModel
属性的ModalContent
一样简单(通过将IsModal
设置为true
来显示之前)。只要您DataTemplate
绑定了ViewModel
(并且MainViewModel
正确实施INotifyPropertyChanged
),就会显示正确的内容。
我想使用模态弹出窗口的一些示例是:
在视图上放置一个按钮以选择客户端。它应该打开一个弹出窗口 所有可能的客户,让用户选择一个。
将产品弹出窗口添加到客户订单。
一旦您理解了上述技术,您应该能够看到,只要您拥有View
和ViewModel
对,就可以涵盖您能想到的任何情景。
例如,考虑具有以下接口的viewModels:
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
的{{1}}属性将以MainViewModel
开头。false
对象。然后该命令会告诉SelectCustomerCommand
将MainViewModel
属性更改为IsSelectingCustomer
。true
将显示数据模板指定的视图。用户现在只能与“选择客户视图”进行交互。ModalContentPresenter
的{{1}}),这反过来会引发CustomerSelectedCommand
事件。SelectCustomerViewModel
会有一个响应CustomerSelected
事件的事件处理程序。然后,处理程序将从MainViewModel
读取CustomerSelected
属性,最后,它会将SelectedCustomer
属性设置为false,从而导致模式内容关闭。