Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
                }
            }
        }
Beispiel #3
0
        /// <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);
                    }
                }
            }
        }
Beispiel #5
0
 public OpenWindowCommand(BaseViewmodel viewModel)
 {
     ViewModel  = viewModel;
     LoginModel = LoginModel;
 }
Beispiel #6
0
        /// <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;
                    }
                }
            }
        }
Beispiel #7
0
 public ExitWindowCommand(BaseViewmodel viewModel)
 {
     this.ViewModel = viewModel;
 }
Beispiel #8
0
        /// <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);
 }