Korzystam z zestawu narzędzi Galasoft Mvvm Light, aby zbudować swoją aplikację w systemie MVVM dla Windows Phone. Mam do stron, które każdy ma swój własny model widoku.Nawigacja i rekonstrukcja stron/viewmodel konstruktor
Gdy użytkownik uruchamia aplikację, może wybrać nową grę i zakręcić stronę z pytaniami. Te strony mają każdy model widoku, a wszystko działa za pomocą narzędzia viewmodellocator. Gdy użytkownik przejdzie z powrotem, aby wybrać nową grę i pytania ponownie. Viewmodel/strona nie jest usuwany. co oznacza, że gdy użytkownik po raz drugi przechodzi do pytań lub nowej gry, konstruktor dla viewmodel nie jest wywoływany, tak że inicjalizacja w konstruktorze nie jest uruchamiana, a widok nie jest ustawiony prawidłowo.
Solutions Próbowałem
Próbowałem usunięcie backstack w nawigacje, takie jak nowej nawigacji do nowej gry lub pytania, należy kręcić nową stronę, a tym samym caling konstruktora. Nie działa.
Użycie załadowanego zdarzenia w widoku i wywołanie konstruktora. Nie działa.
Próbowałem podążać za How to reset all instances in IOC Container Ale nie mogłem go uruchomić, mógłbym po prostu być mną.
Czy ktoś rozwiązuje ten problem, jeśli tak, to jak go rozwiązać?
Kod Tutaj można znaleźć przykład. Naciśnij pytania i naciśnij przycisk tam jeden raz, użyj klawisza wstecz. i ponownie zadawaj pytania. widzisz, że liczba to teraz 1, to można łatwo zmienić. Ale błąd pojawia się, gdy ponownie naciśniesz przycisk. Nagle pojawiają się dwa wyskakujące okienka.
Jaki jest poprawny sposób konfiguracji viewmodel. ponieważ widok nowej gry będzie użyty przy ponownym ładowaniu starej gry, tylko z innymi wartościami, i kiedy ktoś chce rozpocząć nową grę. Mam nadzieję, że rozumiesz :)
Ten przykład pokazuje tylko mój problem z licznikiem wyskakujących okien po każdym powrocie na stronę viewmodel. https://www.dropbox.com/s/gjbz0l8rmsxqzrd/PhoneApp8.rar
ViewModel Locator jestem w moim obecnym projekcie przy użyciu trzech ViewModels widoczne w poniższym kodzie:
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
}
}
Mam spojrzał na link odwołać powyżej zresetowanie wszystkich przypadkach, w MKOl pojemnika. Ale nie wiesz, jak działa klucz i jak upewnić się, że funkcja czyszczenia zostanie wywołana podczas nawigacji z dala od widoków. Ponieważ nie chciałbym wyczyścić wszystkich modeli widoku w tym samym czasie.
Nawigacja i viewmodelbinding
wiążę moją ViewModel do widoku jak
DataContext="{Binding Source={StaticResource Locator},Path=Map}"
poruszać tam iz powrotem przy użyciu NavigationService i BackButton.Z menu do gry:
NavigationService.Navigate(new Uri("/View/MainPage.xaml", UriKind.Relative));
i na stronie
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//e.Content = NavigationMode.New;
//e.NavigationMode = NavigationMode(
ViewModel.MainViewModel test = new ViewModel.MainViewModel();
GC.Collect();
base.OnNavigatedTo(e);
}
iz grę do menu:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
//e.NavigationMode = NavigationMode.
this.DataContext = null;
GC.Collect();
base.OnNavigatedFrom(e);
//test = null;
}
iw menu Wzywam śmieciarza. Jak można zauważyć, przełamuję strukturę MVVM, aby uwzględnić problem.
Myślę, że otrzymasz bardziej szczegółowe odpowiedzi, jeśli możesz opublikować konkretną próbkę demonstrującą problem. Ogólnie rzecz biorąc, myślę, że punktem modelu widoku jest * utrzymywanie * danych na różnych stronach, więc nie powinieneś się dziwić, że widok drugiej strony zachowuje dane z pierwszego widoku. Możesz sobie z tym poradzić, przenosząc część procesu init z konstruktora do funkcji wywoływanej z konstruktora, a także ze zdarzenia ładowanego stronami. – BobHy
Dokładnie to zrobiłem. Istnieje jednak problem z pamięcią, ponieważ model widoku nie jest czyszczony podczas nawigacji. A ponieważ Datacontext jest ustawiony na widok nie mogę uzyskać dostęp do viewmodel z tyłu. Co musiałem zrobić do tej pory było ustawienie datacontext = null i wywołanie GC.collect(). Ale nie jest to dobry sposób na zrobienie tego. Chciałem wiedzieć, jaki jest właściwy sposób. – JTIM
Proszę opublikuj próbkę pokazującą, co aktualnie robisz (z komentarzami pokazującymi, co chciałbyś/chciałabyś/chciałabyś mieć). Posiadanie modelu widoku V1 dla danej strony P1 nadal pozostaje w pamięci, kiedy P1 jest ładowany po raz drugi, to właśnie ma się zdarzyć. Czy widzisz inny model widoku w P1.DataContext? – BobHy