假设我在WPF中有两个页面,即Page1.xaml
和Page2.xaml
。我有一个名为PageViewModel.cs
的视图模型。这两个页面共享相同的视图模型。
我可以通过两种方法编写代码:
Mehod1:
PageViewModel.cs
public static class PageViewModel
{
}
的Page1.xaml
<Window.........>
<Window.DataContext>
<vm:PageViewModel />
</Window.DataContext>
</Window>
Page2.xaml
<Window.........>
<Window.DataContext>
<vm:PageViewModel />
</Window.DataContext>
</Window>
的App.xaml
Default xaml code.
方法2:
PageViewModel.cs
public class PageViewModel
{
}
的Page1.xaml
<Window DataContext={StaticResource PageViewModel}>
..........
..........
</Window>
Page2.xaml
<Window DataContext={StaticResource PageViewModel}>
..........
..........
</Window>
的App.xaml
<vm:PageViewModel x:Key="PageViewModel" />
有人可以解释上述两种方法之间的区别吗?
答案 0 :(得分:6)
主要区别在于,在第一个示例中,任何对象或方法都可以访问您的视图模型,数据及其方法。
在第二个中,你有一个实际的实例(虽然包含在一个全局可访问的对象中),所以虽然其他对象可以仍然可以访问它,但它并不像&#34;访问静态(读取,全局)实例&#34;。
两者具有相同的效果,您可以在两个视图之间共享数据。
您可能需要考虑的另一个选项是将视图模型传递给视图的构造函数。您必须使用代码隐藏,但是您可以为两个视图提供对同一视图模型对象的引用,而无需任何全局变量。
如果这些是子视图,那么您可以执行以下操作:
MainView.xaml.cs
public void MainView()
{
SubViewModel subVm = new SubViewModel();
//If you are instantiating your views
MySubView view1 = new MySubView(subVm);
MySecondSubView view2 = new MySecondSubView(view2);
//Otherwise
view1.DataContext = subVm;
view2.DataContext = subVm;
}
根据定位器模式的精神,您还可以简单地将子视图的DataContext
属性绑定到主视图模型上的SubViewModel
属性。
要注意的一件事是,一旦两个子视图都被销毁,视图模型的生命周期就会结束。如果您需要更长的生命周期,那么您应该使用后一个选项并将其指向一个长期存在的对象。
一般来说,我会远离static
课程。它们进行单元测试,总体上设计良好,难以实现。如果你需要一个单例,至少要正确实现一个而不是只使用一个静态类。
答案 1 :(得分:5)
这不能回答你的问题,BradleyDotNET已经做到了,但我无法在这里帮助我。
这是使用ViewModelLocator的完美示例,尝试安装GalaSoft MVVM Light等框架。您可以使用定位器来跟踪您的视图模型,静态视图模型是坏饼(您将遇到很多可以避免的问题)。
我无法看到您声明静态资源的位置,但我认为它位于App.xaml中?
Check this post for using a viewmodel locator, don't be alarmed by the IOC stuff :)。这非常方便,是解决问题的好方法。
绑定到someviewmodel,假设vmlocator在App.xaml中定义,并且那里存在SomeViewModel。
DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=SomeViewModel}"
希望它有所帮助,
干杯Stian