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

时间:2014-08-25 19:45:55

标签: c# wpf xaml

假设我在WPF中有两个页面,即Page1.xamlPage2.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" />

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

2 个答案:

答案 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