Si encuentras algún detalle que no comprendes puedes comentarlo y haremos todo lo posible de ayudarte lo mas rápido que podamos.
Solución:
Yo suelo usar un ContentControl
para mostrar contenido dinámico. Es Content
la propiedad suele estar ligada a un CurrentViewModel
propiedad en el padre ViewModel
y DataTemplates
se utilizan para decirle a WPF cómo dibujar al niño ViewModels
.
Para cambiar las vistas, simplemente cambie el CurrentViewModel
propiedad en el padre ViewModel
Puedes encontrar un ejemplo en este artículo mío.
Finalmente lo hice de esta manera.
Siguiendo la idea de o_q, creé NavigationWindow como MainWindow y cambié todas las vistas a página.
Luego, creé una interfaz y una clase que usaba Navegación:
public interface INavigationService
event NavigatingCancelEventHandler Navigating;
void NavigateTo(Uri pageUri);
void GoBack();
public class NavigationService : INavigationService
private NavigationWindow _mainFrame;
#region Implementation of INavigationService
public event NavigatingCancelEventHandler Navigating;
public void NavigateTo(Uri pageUri)
if (EnsureMainFrame())
_mainFrame.Navigate(pageUri);
public void GoBack()
if (EnsureMainFrame()
&& _mainFrame.CanGoBack)
_mainFrame.GoBack();
#endregion
private bool EnsureMainFrame()
if (_mainFrame != null)
return true;
_mainFrame = System.Windows.Application.Current.MainWindow as NavigationWindow;
if (_mainFrame != null)
// Could be null if the app runs inside a design tool
_mainFrame.Navigating += (s, e) =>
if (Navigating != null)
Navigating(s, e);
;
return true;
return false;
Luego, en viewModelLocator creé todas las constantes string necesario para almacenar las rutas a mis puntos de vista:
public class ViewModelLocator
#region Views Paths
public const string FrontendViewPath = "../Views/FrontendView.xaml";
public const string BackendViewPath = "../Views/BackendView.xaml";
public const string StartUpViewPath = "../Views/StartUpView.xaml";
public const string LoginViewPath = "../Views/LoginView.xaml";
public const string OutOfOrderViewPath = "../Views/OutOfOrderView.xaml";
public const string OperativeViewPath = "../Views/SubViews/OperativeView.xaml";
public const string ConfigurationViewPath = "../Views/SubViews/ConfigurationView.xaml";
#endregion
En App.cs, en el controlador de eventos Application_Startup, con la ayuda de Unity IoC, registré un singleton de NavigationService:
public partial class App : System.Windows.Application
{
private static IUnityContainer _ambientContainer;
public static IServiceLocator AmbientLocator get; private set;
...
private void Application_Startup(object sender, System.Windows.StartupEventArgs e)
{
_ambientContainer =
new UnityContainer();
_ambientContainer.RegisterType(new ContainerControlledLifetimeManager());
AmbientLocator = new UnityServiceLocator(_ambientContainer);
ServiceLocator.SetLocatorProvider(() => AmbientLocator);
Ahora, en mi ViewModelLocator, puedo registrar un mensaje de “Galasoft” para capturar todos los eventos y navegar a una página; en el constructor tengo:
public ViewModelLocator()
CreateMain();
CreateFrontend();
CreateBackend();
CreateStartUp();
CreateOperative();
CreateLogin();
CreateConfiguration();
CreateOutOfOrder();
// Set Startup Page...
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));
Messenger.Default.Register(this, message =>
switch (message.StateInfo.StateType)
case StateType.StartUpState:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));
break;
case StateType.LoginState:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(LoginViewPath, UriKind.Relative));
break;
case StateType.OperativeState:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OperativeViewPath, UriKind.Relative));
break;
case StateType.ConfigurationState:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(ConfigurationViewPath, UriKind.Relative));
break;
case StateType.ClosedState:
case StateType.OutOfOrderState:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OutOfOrderViewPath, UriKind.Relative));
break;
default:
ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));
break;
);
De esta forma mantengo todos los viewModels “ignorantes”… no saben nada de navegación, además no tengo código detrás.
Si necesito navegar usando un botón desde una vista, puedo resolver NavigationService desde el modelo de vista conectado y navegar a la página que necesito.
Y, lo más importante, ¡funciona!
Te mostramos reseñas y puntuaciones
Si tienes algún reparo y forma de innovar nuestro crónica te recordamos escribir una referencia y con placer lo observaremos.