我对WPF和MVVM都是陌生的,并且在尝试在两个单独的视图中将DataContext
设置为我的ViewModel的同一实例时遇到一个问题。
这是因为:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
将为每个视图创建视图模型的新实例。
为了解决这个问题,我决定创建一个类,该类存储我使用的每个ViewModel的静态实例。然后,在每个视图的cs
文件中,我将DataContext
设置为此静态类中的相应ViewModel。
这可行,但对于大型程序而言似乎不是最好的主意,在大型程序中可能同时需要ViewModel的多个实例。
解决此问题的更好方法是什么-是否有合理的方法使用同一个ViewModel实例拥有多个View?
或者这种方法是不好的做法-我是否应该为每个ViewModel设计一个带有一个View的程序?
谢谢!
答案 0 :(得分:5)
您可以在App.xaml中实例化该视图模型,以便整个应用程序都可以访问它。
<Application.Resources>
<local:ViewModel x:Key="sharedViewModel" />
</Application.Resources>
然后,在您想要使用该数据上下文的视图中,执行以下操作...
DataContext="{StaticResource sharedViewModel}"
答案 1 :(得分:1)
实现ViewModelLocator既简单又容易,也是推荐的方法之一。
想法已在ViewModelLocator类中定义了所有ViewModel,并在需要时访问ViewModel。在不同的视图中使用Same ViewModel不会成为问题。
public class ViewModelLocator
{
private MainWindowViewModel mainWindowViewModel;
public MainWindowViewModel MainWindowViewModel
{
get
{
if (mainWindowViewModel == null)
mainWindowViewModel = new MainWindowViewModel();
return mainWindowViewModel;
}
}
private DataFactoryViewModel dataFactoryViewModel;
public DataFactoryViewModel DataFactoryViewModel
{
get
{
if (dataFactoryViewModel == null)
dataFactoryViewModel = new DataFactoryViewModel();
return dataFactoryViewModel;
}
}
}
App.xaml
xmlns:core="clr-namespace:MyViewModelLocatorNamespace"
<Application.Resources>
<core:ViewModelLocator x:Key="ViewModelLocator" />
</Application.Resources>
用法
<Window ...
DataContext="{Binding Path=MainWindowViewModel, Source={StaticResource ViewModelLocator}}">
请参阅:So Question从那里复制的代码..因为我无法从我的项目中窃取代码。.
答案 2 :(得分:0)
我也有同样的问题,我找不到很好的答案。经过一段时间的思考,我得出的结论是,在大多数情况下,最好在视图模型和视图之间创建一对一的映射。因此,在这种情况下,我将创建两个独立的视图模型,这些视图模型继承自基本视图模型。这样,您可以放入基本视图模型中的所有常见内容,并添加可能与更具体的视图模型不同的任何字段或方法。如果视图模型确实等效,那么您可能想问自己为什么首先要有两个单独的视图。您可以考虑将它们合并为一个视图。可能需要两个单独的视图,但这只是要考虑的事情。
答案 3 :(得分:0)
我正在使用棱镜框架,并且也在寻找一种对多个(子)视图使用一个视图模型的解决方案。在棱镜中有两种可能的解决方案:
根据棱镜文档,我的解决方案如下所示。
在棱镜引导程序中:
Container.RegisterTypeForNavigation<MyView>("MyView");
在视图模型中:
private void DisplayView(string viewName)
{
RegionManager.Regions["ContentRegion"].Context = this; // set viewmodel
RegionManager.RequestNavigate("ContentRegion", viewName);
}
在每个视图后面的代码中:
public MyView()
{
InitializeComponent();
ObservableObject<object> viewRegionContext = RegionContext.GetObservableContext(this);
viewRegionContext.PropertyChanged += this.ViewRegionContext_OnPropertyChangedEvent;
}
private void ViewRegionContext_OnPropertyChangedEvent(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == "Value")
{
var context = (ObservableObject<object>)sender;
DataContext = context.Value; // get viewmodel as DataContext
}
}