Vishal
Vishal

Reputation: 6378

What is the difference between declaring a class as static and creating an instance in app.xaml file?

Suppose I have two Pages in WPF namely Page1.xaml and Page2.xaml. I have one viewmodel named PageViewModel.cs. Both of those pages share the same viewmodel.

I can write my code by two methods:

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.

Method2:

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" />

Can anybody explain the difference between above mentioned two methods?

Upvotes: 2

Views: 145

Answers (2)

BradleyDotNET
BradleyDotNET

Reputation: 61369

The primary difference will be that in your first example, any object or method can access your view model, its data, and its methods.

In the second, you have an actual instance (albeit contained in a globally accessible object), so while other objects could still get to it, its not as easy as "access the static (read, global) instance".

Both have the same effect, you get data shared between the two views.

One additional option you may want to consider would be to pass the view model in on the constructor of the view. You have to use the code-behind, but you can give both view's a reference to the same view model object without having any global variables.

If these are subviews, then you could do the following:

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;
}

In the spirit of the locator pattern, you could also simply bind the DataContext property of the sub views to a SubViewModel property on your main View Model.

The one thing to be aware of with this is that the View Model's lifetime will end once both sub views are destroyed. If you need a longer lifetime, then you should use the latter option and point it towards a long-lived object.

In general, I would stay away from static classes. They make unit testing, and good design in general, much more difficult to achieve. If you need a singleton, at least implement one properly as opposed to just using a static class.

Upvotes: 6

St&#237;gandr
St&#237;gandr

Reputation: 2902

This won't answer your question, BradleyDotNET has done that, but I just can't help my self here.

This is a perfect example for using a ViewModelLocator, try to install a framework such as GalaSoft MVVM Light. You may use your Locator to keep track of your viewmodels, static viewmodels are bad pie(you are going to run into alot of problems you can avoid).

I can't see where you have declared your static resource, but I assume it is in App.xaml ?

Check this post for using a viewmodel locator, don't be alarmed by the IOC stuff :). This is really handy and a great way to solve your issue.

Binding to someviewmodel, assuming the vmlocator is defined in App.xaml and that SomeViewModel is present there.

DataContext="{Binding Source={StaticResource ViewModelLocator},  Path=SomeViewModel}"

Hope it helps,

Cheers Stian

Upvotes: 5

Related Questions