将类声明为静态和在app.xaml文件中创建实例有什么区别?

Vis*_*hal 2 c# wpf xaml

假设我有两页在WPF即Page1.xamlPage2.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)

任何人都可以解释上述两种方法之间的区别吗?

Bra*_*NET 6

主要区别在于,在第一个示例中,任何对象或方法都可以访问您的视图模型,其数据及其方法.

在第二个,你有一个实际的例子(尽管包含在全球访问的对象),所以当其他对象可能仍然得到它,它不是那么容易,因为"访问静态(读,全局)实例".

两者都具有相同的效果,您可以在两个视图之间共享数据.

您可能需要考虑的另一个选项是将视图模型传递给视图的构造函数.您必须使用代码隐藏,但您可以为两个视图提供对同一视图模型对象的引用,而无需任何全局变量.

如果这些是子视图,那么您可以执行以下操作:

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课程.它们进行单元测试,总体上设计良好,难以实现.如果你需要一个单例,至少要正确实现一个而不是只使用一个静态类.


Stí*_*ndr 5

这不会回答你的问题,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

  • 我也会看一个viewmodel定位器模式. (3认同)