2013-05-21 15 views
9

używam Caliburn.Micro wewnątrz aplikacji WinRTCaliburn.Micro ponownie powiązać ContentControl na GoBack nawigacji

Tu jest mój główny VM:

public class MainViewModel : Conductor<Screen> 
{ 
    protected override void OnActivate() 
    { 
     if (ActiveItem == null) 
     { 
      ActivateItem(
       ViewModelLocator.LocateForViewType(typeof(NewsFeedView)) as Screen); 
     } 

     base.OnActivate(); 
    } 
} 

tutaj używam przewodu, ponieważ chcę, aby załadować różne kontrole ContentControl, ale teraz mam tylko ten kod. Oto moja kontrola treści w głównym widoku:

<ContentControl x:Name="ActiveItem" Grid.Column="1" Grid.Row="1" /> 

Kiedy uruchomienie aplikacji wszystko działa grzywny, MainViewModel.Activate jest wywoływana i ActiveItem zestaw do NewsFeedViewModel i ContentControl ładunku NewsFeedView.

Problem:

Kiedy nawigacja w NewsFeedView sterowania do innego widoku za pomocą NavigationService.NavigateToViewModel metodę, a następnie w tym wykorzystania widoku NavigationService.GoBack, Wracam do MainView iw tym momencie MainViewModel.Activate pobiera nazywane ActiveItem nie jest null, ale ContentControl.Content jest null. Próbowałem użyć załączonej usługi View.Model dla ContentControl, ale bez powodzenia, jak ją zmienić?

EDIT: Wreszcie jestem w konfiguracji rejestratora Caliburn aby zobaczyć, co się dzieje, i znalazłem błąd - gdy MAINVIEW załadowany po navigationg back Ten zdarzenia występujące:

Attaching ***.Views.MainView to ***.ViewModels.MainViewModel. 
ViewModel bound on ActiveItem. 
Using cached view for ***.ViewModels.NewsFeedViewModel. 
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Unspecified error 
at Windows.UI.Xaml.Controls.ContentControl.put_Content(Object value) 
... some winRT stack 
at Caliburn.Micro.View.SetContentPropertyCore(... 

Chociaż nie było tak dobrze poinformowany Użyłem InteliTrace, aby uzyskać więcej informacji i otrzymałem tę wiadomość: "Element jest już dzieckiem innego elementu". Przypuszczam, że NewsFeedView przechowywane gdzieś i kiedy nadszedł czas, aby umieścić go w ContentControl ten wyjątek rzucony. Jak rozwiązać ten problem?

+0

Czy sprawdziłeś, czy obiekt MainViewModel nadal jest tą samą instancją, co poprzednio? "Element jest już dzieckiem innego elementu" brzmi, jakbyś nawigował do nowej instancji MainViewModel, ale stary wciąż jest zawieszony na NewsFeedViewModel. Czy możesz udostępnić swoją konfigurację bootstrappera? – T045T

+0

Proszę udostępnić swój bootstrapper. Dzięki temu dowiesz się, jakie masz możliwości. Rozwiązałem taki problem w scenariuszu .net 4.0/wpf. –

+0

@MareInfinitus nie ma bootstrappera w aplikacji WinRT, MainViewModel zarejestrowany jako Singleton w Caliburn IoC pojemnik – Alexander

Odpowiedz

3

Powinieneś przyjąć pierwsze podejście do modelu widoku. Innymi słowy, aktywuj instancję modelu widoku, a Caliburn.Micro zrobi widok widoku i będzie dla ciebie wiążący.

wygląda również jak chcesz po prostu instancję modelu widoku raz w konstruktorze na przykład, albo OnInitialise:

public MainViewModel() 
{ 
    this.ActivateItem(new NewsFeedViewModel()); 
} 
+0

dziękuję za odpowiedź, ale naprawdę nie rozumiem, co masz na myśli przez "adoptuj pierwsze podejście modelu widoku", używam modelu widoku podczas wywoływania 'ActivateItem' oraz podczas wywoływania' NavigateToViewModel' podczas nawigacji między widokami, więc nie używam widoku pierwszy widok tutaj – Alexander

+0

Tak, ale jesteś z kodu MainViewModel, który zawiera powyżej, robisz to w bardzo okrężny sposób. Otrzymujesz model widoku za pomocą ViewModelLocator i typ widoku. Po prostu użyj instancji modelu widoku. – devdigital

+0

OK, zrozumiałe, ale na koniec nie ma to wpływu na wiązanie danych, nadal podczas nawigacji z widoku, ContentControl jest pusty pomimo tego, że 'ActiveItem' nie ma wartości null, próbowałem wywoływać' NotifyOfPropertyChange (() => ActiveItem) ' ale nadal ten sam wynik. – Alexander

1

Inicjalizować News Feed widoku modelu tylko raz jako @devdigital powiedział, prawdopodobnie w konstruktorze i dlaczego nie używać Conductor.Collection.OneActive, ponieważ masz tylko jeden aktywny element w danym momencie, jest on używany w takich sytuacjach, może to rozwiązać twój problem.

Powiązane problemy