如何使用 MVVM Light for WPF 浏览窗口? [英] How to navigate through windows with MVVM Light for WPF?

查看:24
本文介绍了如何使用 MVVM Light for WPF 浏览窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始了一个新项目,其中表示层将由 WPF 完成,MVVM Light 由 GalaSoft 完成.>

我需要很多视图,但我不清楚如何通过窗口管理导航.

首先,MVVM Light 中提供的用于创建新的WPF MVVM 视图"的模板创建了一个新的 Window,它不能用于按帧导航(我的意思是,通过放置一个mainView 中的框架并更改要导航的源路径).

对于我使用模板创建的所有视图,我是否只需要将 Window 更改为 Page?

或者是否有其他方法可以使用 MVVM Light 工具包在 WPF 中执行导航?

解决方案

最终我是这样做的.

按照 o_q 的思路,我创建了 NavigationWindow 作为 MainWindow 并将所有视图更改为页面.

然后,我创建了一个界面和一个使用导航的类:

 公共接口 INavigationService{事件 NavigatingCancelEventHandler 导航;void NavigateTo(Uri pageUri);无效的返回();}公共类导航服务:INavigationService{私人导航窗口_mainFrame;#region INavigationService 的实现公共事件 NavigatingCancelEventHandler 导航;public void NavigateTo(Uri pageUri){如果(确保主框架()){_mainFrame.Navigate(pageUri);}}public void GoBack(){如果(确保主框架()&&_mainFrame.CanGoBack){_mainFrame.GoBack();}}#endregion私人布尔值确保MainFrame(){如果(_mainFrame != null){返回真;}_mainFrame = System.Windows.Application.Current.MainWindow 作为 NavigationWindow;如果(_mainFrame != null){//如果应用程序在设计工具内运行,则可能为 null_mainFrame.Navigating += (s, e) =>{如果(导航!= null){导航(s,e);}};返回真;}返回假;}}

然后,在 viewModelLocator 中,我创建了所有用于存储视图路径的常量字符串:

 公共类 ViewModelLocator{#region 查看路径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}

在 App.cs 中,在 Application_Startup 事件处理程序中,在 Unity IoC 的帮助下,我注册了 NavigationService 的单例:

 公共部分类 App : System.Windows.Application{私有静态 IUnityContainer _ambientContainer;公共静态 IServiceLocator AmbientLocator { 获取;私人订制;}...private void Application_Startup(对象发送者,System.Windows.StartupEventArgs e){_ambientContainer =新的 UnityContainer();_ambientContainer.RegisterType(new ContainerControlledLifetimeManager());AmbientLocator = new UnityServiceLocator(_ambientContainer);ServiceLocator.SetLocatorProvider(() => AmbientLocator);

现在,在我的 ViewModelLocator 中,我可以注册一个Galasoft"消息来捕获所有事件并导航到一个页面;在我的构造函数中:

 public ViewModelLocator(){创建主();创建前端();创建后端();创建启动();创建操作();创建登录();创建配置();CreateOutOfOrder();//设置启动页面...ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));Messenger.Default.Register(this, message =>{开关(message.StateInfo.StateType){案例 StateType.StartUpState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));休息;案例 StateType.LoginState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(LoginViewPath, UriKind.Relative));休息;案例 StateType.OperativeState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OperativeViewPath, UriKind.Relative));休息;案例 StateType.ConfigurationState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(ConfigurationViewPath, UriKind.Relative));休息;案例 StateType.ClosedState:案例 StateType.OutOfOrderState:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(OutOfOrderViewPath, UriKind.Relative));休息;默认:ServiceLocator.Current.GetInstance().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));休息;}});}

通过这种方式,我让所有的 viewModel 保持无知"......他们对导航一无所知,而且我没有背后的代码.

如果我需要使用视图中的按钮进行导航,我可以从连接的 viewModel 解析 NavigationService 并导航到我需要的页面.

而且,最重要的是,它有效!

I've just started a new project in which the presentation layer will be done by WPF and MVVM Light by GalaSoft.

I need a lot of views and it's not clear to me how to manage navigation through windows.

First of all, the templates offered in MVVM Light for creating a new "WPF MVVM View" create a new Window that is not possible to use for navigation by frame (I mean, by putting a frame in mainView and changing the source path to navigate).

Do I simply have to change Window to Page for all the views I create using templates?

Or is there a different way to perform navigation in WPF with the MVVM Light toolkit?

解决方案

Eventually I did it this way.

Following the idea of o_q, I created NavigationWindow as MainWindow and changed all the the views to page.

Then, I created an inteface and a class which using Navigation:

    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;
        }

    }

Then, in viewModelLocator I created all the const string nedded to store the paths to my views:

    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
     }

In App.cs, in the Application_Startup event handler, with the help of Unity IoC I registered a singleton of 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<INavigationService, NavigationService>(new ContainerControlledLifetimeManager());

           AmbientLocator = new UnityServiceLocator(_ambientContainer);
           ServiceLocator.SetLocatorProvider(() => AmbientLocator);

Now, in my ViewModelLocator, I can register a "Galasoft" message to catch all the events and navigate to a page; in the constructor I have:

        public ViewModelLocator()
        {
            CreateMain();
            CreateFrontend();
            CreateBackend();
            CreateStartUp();
            CreateOperative();
            CreateLogin();
            CreateConfiguration();
            CreateOutOfOrder();


            // Set Startup Page...
            ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));

            Messenger.Default.Register<MoveToViewMessage>(this, message =>
            {
                switch (message.StateInfo.StateType)
                {
                    case StateType.StartUpState:

                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath,UriKind.Relative));
                        break;
                    case StateType.LoginState:
                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(LoginViewPath, UriKind.Relative));
                        break;
                    case StateType.OperativeState:
                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(OperativeViewPath, UriKind.Relative));
                        break;
                    case StateType.ConfigurationState:
                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(ConfigurationViewPath, UriKind.Relative));
                        break;
                    case StateType.ClosedState:
                    case StateType.OutOfOrderState:
                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(OutOfOrderViewPath, UriKind.Relative));
                        break;
                    default:
                        ServiceLocator.Current.GetInstance<INavigationService>().NavigateTo(new Uri(StartUpViewPath, UriKind.Relative));
                        break;
                }
            });

        }

In this way I keep all the viewModels "ignorant"... they don't know anything about navigation, plus I don't have code behind.

If I need to navigate by using a button from a view I can resolve NavigationService from the connected viewModel and navigate to the Page I need.

And, most important thing, it works!

这篇关于如何使用 MVVM Light for WPF 浏览窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆