假设我有两页在WPF即Page1.xaml和Page2.xaml.我有一个名为的viewmodel PageViewModel.cs.这两个页面共享相同的viewmodel.
我可以通过两种方法编写代码:
Mehod1:
PageViewModel.cs
public static class PageViewModel
{
}
Run Code Online (Sandbox Code Playgroud)
的Page1.xaml
<Window.........>
<Window.DataContext>
<vm:PageViewModel />
</Window.DataContext>
</Window>
Run Code Online (Sandbox Code Playgroud)
Page2.xaml
<Window.........>
<Window.DataContext>
<vm:PageViewModel />
</Window.DataContext>
</Window>
Run Code Online (Sandbox Code Playgroud)
App.xaml中
Default xaml code.
Run Code Online (Sandbox Code Playgroud)
方法2:
PageViewModel.cs
public class PageViewModel
{
}
Run Code Online (Sandbox Code Playgroud)
的Page1.xaml
<Window DataContext={StaticResource PageViewModel}>
..........
..........
</Window>
Run Code Online (Sandbox Code Playgroud)
Page2.xaml
<Window DataContext={StaticResource PageViewModel}>
..........
..........
</Window>
Run Code Online (Sandbox Code Playgroud)
App.xaml中
<vm:PageViewModel x:Key="PageViewModel" />
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释上述两种方法之间的区别吗?
主要区别在于,在第一个示例中,任何对象或方法都可以访问您的视图模型,其数据及其方法.
在第二个,你有一个实际的例子(尽管包含在全球访问的对象),所以当其他对象可能仍然得到它,它不是那么容易,因为"访问静态(读,全局)实例".
两者都具有相同的效果,您可以在两个视图之间共享数据.
您可能需要考虑的另一个选项是将视图模型传递给视图的构造函数.您必须使用代码隐藏,但您可以为两个视图提供对同一视图模型对象的引用,而无需任何全局变量.
如果这些是子视图,那么您可以执行以下操作:
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;
}
Run Code Online (Sandbox Code Playgroud)
根据定位器模式的精神,您还可以简单地将DataContext子视图的SubViewModel属性绑定到主视图模型上的属性.
需要注意的一件事是,一旦两个子视图都被销毁,View Model的生命周期就会结束.如果您需要更长的生命周期,那么您应该使用后一个选项并将其指向一个长寿命的对象.
一般来说,我会远离static课程.它们进行单元测试,总体上设计良好,难以实现.如果你需要一个单例,至少要正确实现一个而不是只使用一个静态类.
这不会回答你的问题,BradleyDotNET已经做到了,但我无法帮助自己.
这是使用ViewModelLocator的完美示例,尝试安装GalaSoft MVVM Light等框架.您可以使用定位器来跟踪您的视图模型,静态视图模型是坏饼(您将遇到很多可以避免的问题).
我看不到你声明静态资源的位置,但我认为它在App.xaml中?
查看这篇文章是否使用了viewmodel定位器,不要被IOC的东西惊吓:).这非常方便,是解决问题的好方法.
绑定到someviewmodel,假设vmlocator在App.xaml中定义,并且SomeViewModel存在于那里.
DataContext="{Binding Source={StaticResource ViewModelLocator}, Path=SomeViewModel}"
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你,
干杯Stian