2012-06-10 7 views
10

Acabo de empezar a desarrollar mi nueva aplicación Windows 8 la semana pasada usando mvvm light. Estoy familiarizado con la navegación de mvvmlight WP7. Cómo puedo lograr lo mismo en Windows 8. ¿Puede alguien sugerir un mejor método para lograr lo mismo en Windows 8. Encontré una solución, donde anulamos eventos vnavegables en vm y manejamos navegamos a otra página. Pero creo que ese método es obsoleto. Cualquiera, por favor, guíame con la implementación adecuada. Gracias por adelantado.Navegación de página a través de ViewModel usando MVVMLight en Windows 8

+0

¿podría compartir su solución, cómo overrided OnNavigatedTo en vm? –

Respuesta

15

Entiendo que esta no es la respuesta exacta que puede estar buscando, pero esto puede darle algunas ideas para explorar.

En mi caso, no estoy usando MVVMLight, sino mi propia implementación simple de MVVM. Utilizo la clase BindableBase (que viene con las plantillas RC de VS 2012 predeterminadas) para las notificaciones de propiedades. Me imagino que podrías usar MVVMLight para darte algo de la infraestructura, que puedes complementar con algo como el siguiente.

Para la navegación, que definen una interfaz que se parece a:

e implementar de la siguiente manera:

using System; 
using System.Collections.Generic; 
using System.Threading.Tasks; 
using Windows.UI.Xaml.Controls; 

public class NavigationService : INavigationService 
{ 
    private readonly Frame _frame; 

    public NavigationService(Frame frame) 
    { 
     _frame = frame; 
     _frame.Navigated += OnFrameNavigated; 
    } 

    private void OnFrameNavigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e) 
    { 
     var view = e.Content as IView; 
     if (view == null) 
      return; 

     var navMsg = new NavigationMessage() 
     { 
      Sender = this, 
      NewView = view, 
      Parameter = e.Parameter, 
      NavigationMode = (int)e.NavigationMode 
     }; 

     EventManager.Current.Publish(navMsg); 

     //Anything that the parent needs to be notified should happen in of after this method 
     var viewModel = view.ViewModel; 
     if (viewModel != null) 
      viewModel.Initialise(e.Parameter); 
    } 

    public void Navigate(Type pageType) 
    { 
     DisposePreviousView(); 
     _frame.Navigate(pageType); 
    } 

    public void Navigate(Type pageType, object parameter) 
    { 
     DisposePreviousView(); 
     _frame.Navigate(pageType, parameter); 
    } 

    private void DisposePreviousView() 
    { 
     var currentView = this.CurrentView; 
     var currentViewDisposable = currentView as IDisposable; 
     if (currentViewDisposable != null) 
     { 
      currentViewDisposable.Dispose(); 
      currentViewDisposable = null; 
     } //view model is disposed in the view implementation 
    } 

    public void EnsureNavigated(Type pageType, object parameter) 
    { 
     var currentView = this.CurrentView; 
     if (currentView == null || currentView.GetType() != pageType) 
     { 
      Navigate(pageType, parameter); 
     } 
    } 

    public IView CurrentView 
    { 
     get { return _frame.Content as IView; } 
    } 


    public bool CanGoBack 
    { 
     get { return _frame != null && _frame.CanGoBack; } 
    } 

    public void GoBack() 
    { 
     // Use the navigation frame to return to the previous page 
     if (_frame != null && _frame.CanGoBack) _frame.GoBack(); 
    } 

    public bool CanGoForward 
    { 
     get { return _frame != null && _frame.CanGoForward; } 
    } 

    public void GoForward() 
    { 
     // Use the navigation frame to return to the previous page 
     if (_frame != null && _frame.CanGoForward) _frame.GoForward(); 
    } 

} 

IView:

public interface IView : IDisposable 
{ 
    IViewModel ViewModel { get; } 
    void Refresh(); 
} 

IViewModel:

public interface IViewModel : INotifyPropertyChanged, IDisposable 
{ 
    void Initialise(object parameter); 
    string ViewTitle { get; } 
    void Refresh(); 
} 

Por último, en la página XAML, definir un elemento Frame:

<Frame x:Name="ContentFrame" /> 

Y en el código subyacente de la página: (esto en la única parte fea en mi opinión - pero su esperemos que no sea demasiado malo):

var _navigationService = new NavigationService(this.ContentFrame); 

ahora puede pasar el _navigationService al modelo de vista. En mi caso, creo el modelo de vista en el código detrás de la página:

public HomePage() 
{ 
    this.InitializeComponent(); 

    var _navigationService = NavigationService.GetFor(this.ContentFrame); 

    DataContext = new HomePageViewModel(_navigationService); 

} 

Hope this helps.

+0

+1 - Me gusta este enfoque. Para "la parte fea", podría usar un contenedor DI para que no tenga que pasar el servicio al modelo de vista en el código de la vista detrás. – EkoostikMartin

+0

La última versión de MVVMLight tiene un SimpleIoc que pone esto en juego con algunas líneas de código. –

4

Lea el artículo publicado en MSDN Magazine recientemente por el propio Laurent Bugnion en el trabajo con el Kit de herramientas de MVVM Light y Windows 8.

Hacia el final del artículo explica exactamente cómo configurar el NavigationService que necesita.

http://msdn.microsoft.com/en-us/magazine/jj651572.aspx

Cuestiones relacionadas