2013-05-21 13 views
9

sto usando Caliburn.Micro all'interno dell'applicazione WinRTCaliburn.Micro rebind ContentControl su GoBack navigazione

Qui è il mio principale VM:

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

     base.OnActivate(); 
    } 
} 

qui io uso conduttore perché voglio caricare diversi controlli in ContentControl, ma ora ho solo questo codice. Ecco il mio controllo dei contenuti in vista principale:

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

Quando si esegue l'applicazione funzionare tutto bene, MainViewModel.Activate viene chiamato e ActiveItem insieme a NewsFeedViewModel e ContentControl carichi NewsFeedView.

Il problema:

Se navigando in NewsFeedView controllo a un altro vista utilizzando NavigationService.NavigateToViewModel metodo e poi in quella uso vista NavigationService.GoBack, sto tornando a MainView e in quel momento in cui viene chiamato MainViewModel.ActivateActiveItem non è null, ma ContentControl.Content è null. Ho provato ad usare la proprietà allegata View.Model per ContentControl ma non fortuna, come farla ricomporre?

EDIT: Finalmente sto logger di installazione in Caliburn per vedere cosa succede e ho trovato un errore - quando MainView caricato dopo navigationg indietro questi eventi si verificano:

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(... 

Anche se non era così informativo Ho usato InteliTrace per ottenere maggiori informazioni e ho ricevuto questo messaggio: "L'elemento è già figlio di un altro elemento". Immagino che NewsFeedView sia stato archiviato da qualche parte e quando arriva il momento di metterlo in ContentControl questa eccezione viene lanciata. Come risolvere questo?

+0

Hai controllato se l'oggetto MainViewModel è ancora la stessa istanza di prima? "L'elemento è già figlio di un altro elemento" sembra che tu stia navigando verso una nuova istanza di MainViewModel, ma quella vecchia è ancora in agguato su NewsFeedViewModel. Puoi condividere la configurazione del tuo bootstrapper? – T045T

+0

Si prega di condividere il bootstrapper. Questo ti dirà quali possibilità hai. Ho risolto un problema simile in uno scenario .net 4.0/wpf. –

+0

@MareInfinitus non c'è bootstrapper nell'app WinRT, MainViewModel registrato come Singleton nel contenitore Caliburn IoC – Alexander

risposta

3

È necessario adottare il primo approccio del modello di vista. In altre parole, attiva un'istanza di un modello di visualizzazione e Caliburn.Micro eseguirà la vista e rileggerà per te.

Sembra inoltre che si desidera istanziare solo il modello di vista una volta nel costruttore per esempio, o OnInitialise:

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

grazie per una risposta, ma davvero non capisco cosa intendi per "adottare il primo approccio del modello di vista", sto usando il modello di vista quando si chiama 'ActivateItem' e quando si chiama' NavigateToViewModel' durante la navigazione tra le viste, quindi non sto usando il primo approccio qui qui – Alexander

+0

Sì, ma dal codice MainViewModel che hai incluso sopra, lo stai facendo in un strada molto rotonda. Stai ottenendo il modello di visualizzazione utilizzando ViewModelLocator e il tipo di visualizzazione. Basta usare l'istanza del modello di vista in primo luogo. – devdigital

+0

ok, capito, ma alla fine questo non ha alcun effetto sul databinding, ancora quando si torna indietro dalla vista, ContentControl è vuoto nonostante che 'ActiveItem' non sia nullo, ho provato a chiamare' NotifyOfPropertyChange (() => ActiveItem) ' ma ancora lo stesso risultato – Alexander

1

Inizializzare la vista di alimentazione modello notizia solo una volta come @devdigital Detto questo, probabilmente nel costruttore e perché non utilizzare Conductor.Collection.OneActive poiché hai un solo oggetto attivo in un dato momento, viene utilizzato per queste situazioni, questo potrebbe risolvere il tuo problema.

Problemi correlati