/// <summary> /// Overrides the page's OnNavigatedFrom method and calls the Viewmodel's /// <see cref="MVVMbasics.Viewmodels.BaseViewmodel.OnNavigatedFrom">OnNavigatedFrom</see> method. /// </summary> /// <param name="e"></param> protected override void OnNavigatedFrom(NavigationEventArgs e) { InstantiateViewmodel(); if (Viewmodel != null) { ViewState viewState; if (e.NavigationMode == NavigationMode.Back || IsMvvmBasicsBackNavigation()) { viewState = ViewState.Closed; // switching to the previous page inside the App } else { viewState = ViewState.Deactivated; // switching to another page inside the App } Viewmodel.OnNavigatedFrom(viewState); } // Ensure that the page can correctly be disposed DataContextChanged -= View_DataContextChanged; Viewmodel = null; DataContext = null; Window.Current.VisibilityChanged -= OnWindowVisibilityChanged; base.OnNavigatedFrom(e); }
/// <summary> /// Retrieves a View and navigates to the corresponding window. /// </summary> public void NavigateTo <T>(ParameterList parameters) where T : BaseViewmodel { if (_mappings.ContainsKey(typeof(T))) { // If the currently active Viewmodel is registered in the Application class, call the OnNavigatedFrom // event on this Viewmodel! var application = Application.Current as BaseApplication; if (application != null) { BaseViewmodel currentViewmodel = application.CurrentViewmodel; if (currentViewmodel != null) { currentViewmodel.OnNavigatedFrom(ViewState.Deactivated); } } // Now actually instantiate and open the new window BaseView window = (BaseView)Activator.CreateInstance(_mappings[typeof(T)]); _windowStack.Add(window); window.Initialize(parameters); window.ShowDialog(); // Returns only after the new window has been closed // After the new window has been closed (either through NavigateBack or through the X button), pass // parameters to the previous window (since this is the window that will be reactivated) if (_windowStack.Count > 1) { var previousWindow = _windowStack[_windowStack.Count - 2] as BaseView; if (previousWindow != null) { previousWindow.Initialize(_backParameters); _backParameters = new ParameterList(); } } else { if (Application.Current != null) // For non-WPF-applications, this is NULL and the App's main window // can therefore not be retrieved // (due to this, passing back parameters will not work in those // Applications) { // If no previous window is found on the back stack, the App's main window is our target: var previousWindow = Application.Current.MainWindow as BaseView; if (previousWindow != null) { previousWindow.Initialize(_backParameters); _backParameters = new ParameterList(); } } } // Finally remove the closing window from the back stack: if (_windowStack.Count > 0) { _windowStack.RemoveAt(_windowStack.Count - 1); } } }
/// <summary> /// Whenever the view's DataContext changes, set its Viewmodel and (if implementing the <code>IBindableView</code> /// interface) Vm properties accordingly. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void View_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) { if (DataContext == null) { return; } // Retrieve the current DataContext value - this is the Viewmodel instance Viewmodel = (BaseViewmodel)DataContext; // If not done already, inject a reference to the global dispatcher helper into the Viewmodel if (Viewmodel.DispatcherHelper == null) { Viewmodel.DispatcherHelper = new DispatcherHelper(); } //TODO: remove deprecated // If a ServiceLocator has been registered in the BaseApplication, and if the Viewmodel does not yet // know about it: // Inject ServiceLocator into Viewmodel (it will automatically be notified about the // ServiceLocator's availability by the ServiceLocator's setter method). #pragma warning disable 618 var application = Application.Current as BaseApplication; if (application != null) { if (Viewmodel.ServiceLocator == null && application.ServiceLocator != null) { Viewmodel.ServiceLocator = application.ServiceLocator; } } #pragma warning restore 618 // If implementing the IBindableView interface, also store the current viewmodel in the view's Vm property if (this.GetType().GetTypeInfo().ImplementedInterfaces .Any(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IBindableView <>))) { var vmProperty = this.GetType().GetRuntimeProperty("Vm"); if (vmProperty != null) { vmProperty.SetMethod.Invoke(this, new[] { DataContext }); } } }
/// <summary> /// Navigates to the last page on the back stack. /// </summary> public void NavigateBack() { if (_backStack.Count > 0) { var application = Application.Current as BaseApplication; if (application != null) { Frame frame = application.RootFrame; if (frame != null) { // Since we manage the back stack on our own instead of relying on the built-in back stack and // navigation, we cannot simply call frame.NavigateBack() // Instead, retrieve the Viewmodel instance of the View that is about to be reactivated from the // back stack, store it in the BackNavigationViewmodel property for the page to pick it up, call // frame.Navigate() and remove the retrieved Viewmodel instance from the back stack. BaseViewmodel previousViewmodel = _backStack[_backStack.Count - 1]; TypeInfo type = (TypeInfo)Retrieve(previousViewmodel.GetType()); IsBackNavigation = true; BackNavigationViewmodel = previousViewmodel; // Keep the system page stack correctly sized for (int i = 0; i < 2 && frame.BackStack.Count > 0; ++i) { // Remove two pages: the one we're leaving, and the one we're going back to (which will be // added to the stack by frame.Navigate(...)) frame.BackStack.RemoveAt(frame.BackStack.Count - 1); } // Now, actually do navigate... frame.Navigate(type.AsType()); // ...and keep the internal back stack clear _backStack.RemoveAt(_backStack.Count - 1); } } } }
public OpenWindowCommand(BaseViewmodel viewModel) { ViewModel = viewModel; LoginModel = LoginModel; }
/// <summary> /// Internally used method that tries to find the Viewmodel registered to the View, and instantiates it if /// necessary. /// </summary> private void InstantiateViewmodel() { // If Viewmodel is already known by the View, nothing to do here... if (Viewmodel == null) { // If a Viewmodel has been registered to this View, and if it has not been referenced as DataContext, // then get the Viewmodel type from the MvvmNavigationTarget attribute, instantiate it, pass a // reference to the ServiceLocator if requested, and set this instance as the View's DataContext if (DataContext == null && this.GetType().GetCustomAttributes(typeof(MvvmNavigationTargetAttribute), false).Length > 0) { Type viewmodelType = ((MvvmNavigationTargetAttribute)this.GetType().GetCustomAttributes(typeof(MvvmNavigationTargetAttribute), false).First()) .GetViewmodel(); object instance = null; var application = Application.Current as BaseApplication; if (application != null) { //TODO: remove deprecated // If a ServiceLocator has been registered in the BaseApplication, and if the Viewmodel does not yet // know about it: // Inject ServiceLocator into Viewmodel (it will automatically be notified about the // ServiceLocator's availability by the ServiceLocator's setter method). if (viewmodelType.GetConstructors().Any(c => c.GetParameters().Count() == 1 && c.GetParameters()[0].ParameterType == typeof(ServiceLocator))) { #pragma warning disable 618 instance = Activator.CreateInstance(viewmodelType, application.ServiceLocator); #pragma warning restore 618 } else { instance = application.Resolve(viewmodelType); } } if (instance == null && viewmodelType.GetConstructors().Any(c => !c.GetParameters().Any())) { instance = Activator.CreateInstance(viewmodelType); } if (instance != null) { DataContext = instance; } } // If this View's DataContext has been set (either by the user, or by the code snippet above), we assume // that the DataContext is an instance of the Viewmodel and store it if (DataContext != null) { Viewmodel = (BaseViewmodel)DataContext; // If not done already, inject a reference to the global dispatcher helper into the Viewmodel if (Viewmodel.DispatcherHelper == null) { Viewmodel.DispatcherHelper = new DispatcherHelper(); } //TODO: remove deprecated // If a ServiceLocator has been registered in the BaseApplication, and if the Viewmodel does not yet // know about it: // Inject ServiceLocator into Viewmodel (it will automatically be notified about the // ServiceLocator's availability by the ServiceLocator's setter method). #pragma warning disable 618 var application = Application.Current as BaseApplication; if (application != null) { if (Viewmodel.ServiceLocator == null && application.ServiceLocator != null) { Viewmodel.ServiceLocator = application.ServiceLocator; } } #pragma warning restore 618 } } // In a Viewmodel has been registered to this View (either by the code snippet above, or by an earlier // method), register it as currently active Viewmodel in the Application if (Viewmodel != null) { if (Application.Current != null) { if (Application.Current is BaseApplication) { (Application.Current as BaseApplication).CurrentViewmodel = Viewmodel; } } } }
public ExitWindowCommand(BaseViewmodel viewModel) { this.ViewModel = viewModel; }
/// <summary> /// Internally used method that tries to find the Viewmodel registered to the View, and instantiates it if /// necessary. /// </summary> private void InstantiateViewmodel() { // If Viewmodel is already known by the View, nothing to do here... if (Viewmodel == null) { // ...otherwise, if DataContext is not set yet and if we are navigating backwards, set the DataContext // to the Viewmodel instance that has been kept within the back stack if (BindingContext == null) { if (IsMvvmBasicsBackNavigation()) { if (NavigatorServiceReference != null) { BindingContext = NavigatorServiceReference.BackNavigationViewmodel; NavigatorServiceReference.BackNavigationViewmodel = null; } } } // If a Viewmodel has been registered to this View, and if it has not been referenced as DataContext, // then get the Viewmodel type from the MvvmNavigationTarget attribute, instantiate it, pass a // reference to the ServiceLocator if requested, and set this instance as the View's DataContext var attribute = this.GetType().GetTypeInfo().GetCustomAttribute <MvvmNavigationTargetAttribute>(false); if (BindingContext == null && attribute != null) { Type viewmodelType = attribute.GetViewmodel(); object instance = null; var application = Application.Current as BaseApplication; if (application != null) { //TODO: remove deprecated // If a ServiceLocator has been registered in the BaseApplication, and if the Viewmodel does not yet // know about it: // Inject ServiceLocator into Viewmodel (it will automatically be notified about the // ServiceLocator's availability by the ServiceLocator's setter method). if (viewmodelType.GetTypeInfo().DeclaredConstructors.Any(c => c.GetParameters().Count() == 1 && c.GetParameters()[0].ParameterType == typeof(ServiceLocator))) { #pragma warning disable 618 instance = Activator.CreateInstance(viewmodelType, application.ServiceLocator); #pragma warning restore 618 } else { instance = application.Resolve(viewmodelType); } } if (instance == null && viewmodelType.GetTypeInfo().DeclaredConstructors.Any(c => !c.GetParameters().Any())) { instance = Activator.CreateInstance(viewmodelType); } if (instance != null) { BindingContext = instance; } } // If this View's DataContext has been set (either by the user, or by the code snippet above), we assume // that the DataContext is an instance of the Viewmodel and store it if (BindingContext != null) { Viewmodel = (BaseViewmodel)BindingContext; // If not done already, inject a reference to the global dispatcher helper into the Viewmodel if (Viewmodel.DispatcherHelper == null) { Viewmodel.DispatcherHelper = new DispatcherHelper(); } //TODO: remove deprecated // If a ServiceLocator has been registered in the BaseApplication, and if the Viewmodel does not yet // know about it: // Inject ServiceLocator into Viewmodel (it will automatically be notified about the // ServiceLocator's availability by the ServiceLocator's setter method). #pragma warning disable 618 var application = Application.Current as BaseApplication; if (application != null) { if (Viewmodel.ServiceLocator == null && application.ServiceLocator != null) { Viewmodel.ServiceLocator = application.ServiceLocator; } } #pragma warning restore 618 } } }
public NewConnectionCommand(BaseViewmodel viewModel) { this.ViewModel = viewModel; }
/// <summary> /// Stores the currently closing View's Viewmodel instance on the back stack, in order to be able to re-assign /// it whenever this View will be reactivated again. /// Gets called from within BaseView's OnNavigatingFrom method. /// </summary> /// <param name="viewmodel">Viewmodel instance of the View that is currently being closed</param> internal void AddToBackstack(BaseViewmodel viewmodel) { _backStack.Add(viewmodel); }