如何为多视图WPF EF MVVM重用实体框架数据源

如何为多视图WPF EF MVVM重用实体框架数据源,wpf,entity-framework,mvvm,user-controls,binding,Wpf,Entity Framework,Mvvm,User Controls,Binding,您好,我正在使用WPF4、EF和MVVM设计一个应用程序。我希望能够创建可重用的UserControl,以便在应用程序的多个窗口中使用,并让它们从同一个源中绘制数据 假设我有一个GraphView组件和一个TableView组件,它们可以出现在应用程序的同一页面上或不同位置,我希望它们都反映过滤后的EF实体的相同集合。MVVM的常见实践似乎要求每个视图都有自己的viewmodel。但是我是否应该使用联合视图模型并将两者绑定到它,这样如果更改数据或过滤器,两者都将同时更新?如果不是,我该如何处理

您好,我正在使用WPF4、EF和MVVM设计一个应用程序。我希望能够创建可重用的UserControl,以便在应用程序的多个窗口中使用,并让它们从同一个源中绘制数据

假设我有一个GraphView组件和一个TableView组件,它们可以出现在应用程序的同一页面上或不同位置,我希望它们都反映过滤后的EF实体的相同集合。MVVM的常见实践似乎要求每个视图都有自己的viewmodel。但是我是否应该使用联合视图模型并将两者绑定到它,这样如果更改数据或过滤器,两者都将同时更新?如果不是,我该如何处理


谢谢你的建议

在使用EF仅仅四天之后,我就知道您的EF类位于项目级别。我的第一反应是实现一个单例,其中包含对要在viewmodels中保持公共的实体的引用。当然,这将在您的单例上创建一个类依赖


这实际上听起来像是Unity、MEF或其他将进行依赖注入的东西解决的设计问题。您可以将EF类放在其中一个框架的模块中,并使用它们的协议在EF和VM之间进行协调。然后,过滤器或EF中数据的更改也会触发VM可以注册接收的消息,以触发UI更改或VM状态更改或其他任何更改

我完全同意一视图模型一视图的方法。对于共享数据,您可以传递引用(冗长且容易出错),可以使用DI(取决于您的舒适度,但不能很好地处理设计时数据),或者可以在App.xaml.cs中创建静态属性,然后在整个应用程序中共享和访问这些属性。从长远来看,DI可能会得到其他人的最大支持。

一种方法是使用两个视图模型,每个视图/用户控件对应一个视图模型,然后将它们嵌套到某个顶级或更高级的视图模型中。例如,如果两个视图都位于一个主窗口视图中,则可能如下所示:

公共类MainWindowViewModel
{
公共主窗口视图模型(IRepository存储库)
{
SharedUserControlData sharedData=新的SharedUserControlData()
{
MyCollection=新的可观察到的集合(
repository.GetMyEntities()),
//实例化其他共享数据属性
}
UserControl1ViewModel=新的UserControl1ViewModel(sharedData);
UserControl2ViewModel=新的UserControl2ViewModel(sharedData);
}
public UserControl1ViewModel UserControl1ViewModel{get;private set;}
public UserControl2ViewModel UserControl2ViewModel{get;private set;}
//更多的东西。。。
}
您有一个
SharedUserControlData
类,该类包含两个视图都可以绑定到的属性:

公共类SharedUserControlData:INotifyPropertyChanged
{
公共ObservableCollection MyCollection{get;set;}
//其他属性
//INotifyPropertyChanged实现
}
UserControls的ViewModels会注入这些数据:

公共类UserControl1ViewModel
{
公共用户控制1视图模型(SharedUserControlData数据)
{
SharedUserControlData=数据;
}
公共SharedUserControlData SharedUserControlData{get;private set;}
//更多的东西
}
//UserControl2ViewModel也是如此
您的UserControl视图通过DataTemplate绑定到ViewModels:


//UserControl2ViewModel也是如此
然后,UserControls中的一些控件被绑定到
SharedUserControlData.MyCollection
和UserControlViewModels的其他属性。MainWindow的DataContext是MainWindowViewModel:

IRepository repository=new MyRepository();//或者使用依赖注入
主窗口=新的主窗口();
MainWindowViewModel viewModel=新的MainWindowViewModel(存储库);
window.DataContext=viewModel;
在主窗口的XAML中,我们将UserControls绑定到主窗口的DataContext(即MainWindowViewModel)的嵌套ViewModels:



这样,两个UserControl都将具有不同的ViewModel,但都共享相同的SharedData实例,该实例来自包含两个UserControl的ViewModel的更高级别的ViewModel。然后,存储库可以访问EF数据上下文。(这里有存储库只是一个示例,您还可以注入服务类的实例或其他内容。)

您可以看看图书库示例应用程序。对于实体框架提供的相同数据源,它包含两个不同的视图(BookListView[Master],BookView[Detail])。

非常感谢提供了全面的示例!非常感谢。我会调查的。非常感谢你的回复。