I am using Galasoft Mvvm Light toolkit, to build my application in the MVVM pattern for windows phone. I have to pages that each have their own viewmodel.
When a user starts the app he can choose new game og spin up a questions page. These to pages have each a viewmodel, and everything works using the viewmodellocator. When the user then navigates back to choose between new game and questions again. The viewmodel/page is not removed. which means when the user a second time goes into questions or new game, the constructor for the viewmodel is not called, such that the initialisation in the constructor is not run, and the view is not set correctly.
Solutions I have tried
I tried removing the backstack in the navigations, such as a new navigation to new game or questions, should spin up a new page, and thereby caling the constructor. Not working.
USing the loaded event in the view, and calling the constructor. Not working.
Tried to follow How to reset all instances in IOC Container But could not get it to work, might just be me.
Have anyone solve this issue, if so how should it be solved?
Code Here you can find an example. Press questions, and press the button in there once, use backkey. and press questions again. you see that the number is now 1, this could easily be changed. But the error comes when you press the button again. Suddenly two popups are shown.
So what is the correct way to set up the viewmodel. since the view of newgame will be used when reloading an old game, just with other values, and when one wants to start a new game. Hope you understand :)
This example is only to show my problem with popups count going up for each return to the viewmodel page. https://www.dropbox.com/s/gjbz0l8rmsxqzrd/PhoneApp8.rar
ViewModel Locator I am in my current project using three viewmodels seen in the below code:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
namespace MVVMTestApp.ViewModel
{
public class ViewModelLocator
{
public ViewModelLocator()
{
//Holder styr på ViewModels
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
//Tilføj linje her for hver ViewModel
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<MainViewModelTest>();
SimpleIoc.Default.Register<MenuViewModel>();
}
//Tilføj metode som denne for hver ViewModel
public MainViewModel Map
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public MainViewModelTest Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModelTest>();
}
}
public MenuViewModel Menu
{
get
{
return ServiceLocator.Current.GetInstance<MenuViewModel>();
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
I have looked into the link I reference above resetting all instances in IOC Container. But are unsure how the key works, and how to make sure the cleanup function is called when navigating away from the views. Since I would not want to clean all the viewmodels at the same time.
Navigation And viewmodelbinding
I bind my viewmodel to the view as
DataContext="{Binding Source={StaticResource Locator},Path=Map}"
I navigate back and forth using NavigationService and backbutton. From Menu to Game:
NavigationService.Navigate(new Uri("/View/MainPage.xaml", UriKind.Relative));
and in the page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//e.Content = NavigationMode.New;
//e.NavigationMode = NavigationMode(
ViewModel.MainViewModel test = new ViewModel.MainViewModel();
GC.Collect();
base.OnNavigatedTo(e);
}
and from Game to Menu:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
//e.NavigationMode = NavigationMode.
this.DataContext = null;
GC.Collect();
base.OnNavigatedFrom(e);
//test = null;
}
And in the menu I invoke the garbage collector. As can be seen I break the MVVM structure to accommodate the problem.
Navigation is the art and science of determining the position of a ship, plane or other vehicle, and guiding it to a specific destination. Navigation requires a person to know the vehicle's relative location, or position compared to other known locations. Navigators measure distance on the globe in degrees.
Navigation, derived from the Latin words "navis" (meaning "ship") and "agere" (meaning "to drive") is the process of accurately determining the position and controlling the movement of a craft or vehicle along a desired course.
Three main types of navigation are celestial, GPS, and map and compass. In order to better understand why we teach map and compass at High Trails, it is helpful to learn the basics of all three techniques.
Properties of your ViewModelLocator return Singletons. To make the property return a new instance each time you could simply write:
private int questCount;
public Question Quest
{
get
{
return ServiceLocator.Current.GetInstance<Question>((++questCount).ToString());
}
}
However, it will result in Question ViewModel caching. You need to release unused ViewModels by closely following the answer you linked. This results in my opinion in too much code for a simple result. There are other IOC Containers that you could use in place of SimpleIoc
on Windows Phone (like ninject or unity), which may be better suited for your needs.
In a simple project (a couple-of-pages app), especially in the case of not having to much experience with IOC container, I would advise you to abandon all that SimpleIoc wiring and just call the constructor:
public Question Quest
{
get { return new Question(); }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With