美文网首页程序员
MVVMLight的流程简单分析(二)

MVVMLight的流程简单分析(二)

作者: 浅浅的笑意 | 来源:发表于2018-01-06 18:48 被阅读0次

    时间过得可真快,转眼就2018年了。

    2018年的第一篇文章,就继续简单讲一下mvvmlight的整个应用启动的那些部分,为了避免自己忘记。


    App启动

    APP分部类

    首先关注的肯定是APP类启动的地方,我们从app.xaml.cs开始着手。我们看到有好几个函数,因为是讲流程,所以就不每个函数都介绍过去了,这里重点关注那个OnLaunched函数。这个是App一开始启动调用的函数。

    从注释也可以看出,这是在用户启动应用是触发调用。

            protected override void OnLaunched(LaunchActivatedEventArgs e)
            {
                //TODO: 中文为自己添加的注释说明
    
                //首先获取当前窗口的内容
                Frame rootFrame = Window.Current.Content as Frame;
    
                // Do not repeat app initialization when the Window already has content,
                // just ensure that the window is active
                //如果内容也就是框架Frame为空,则创建一个新的,并放置到窗口中
                if (rootFrame == null)
                {
                    // Create a Frame to act as the navigation context and navigate to the first page
                    rootFrame = new Frame();
    
                    rootFrame.NavigationFailed += OnNavigationFailed;
    
                    if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                    {
                        //TODO: Load state from previously suspended application
                    }
    
                    // Place the frame in the current Window
                    Window.Current.Content = rootFrame;
                }
    
                //全新应用启动时,会进入这个if条件中
                if (e.PrelaunchActivated == false)
                {
                    //判断框架中是否存在内容,主要是页面Page类
                    if (rootFrame.Content == null)
                    {
                        // When the navigation stack isn't restored navigate to the first page,
                        // configuring the new page by passing required information as a navigation
                        // parameter
                        //初始时,导航栈肯定为空,我们需要导航到第一页,即放置内容到框架中。
                        //这个页面就是我们的首页,或者说主页面。
                        rootFrame.Navigate(typeof(MainPage), e.Arguments);
                    }
                    // Ensure the current window is active
                    Window.Current.Activate();
                }
                //这里是MVVMLight框架封装的一个调度工具
                //主要的用处是让我们可以在非UI线程中,可以委托调度器帮我们去完成UI的操作
                //在此处初始化
                DispatcherHelper.Initialize();
    
                //MVVMLight在此处注册了一个消息,
                //我们可以看到上图中的那个函数就是消息的回调
                //自己暂时没用过这个封装的消息工具
                Messenger.Default.Register<NotificationMessageAction<string>>(
                    this,
                    HandleNotificationMessage);
            }
    

    当然我们知道这个是App的分部类,那么其他的部分在app.xaml文件中。而在那里,声明了很重要的东西。我们接着往下看。

    App分部类

    这是一个xaml文件,我们不需要理会那些声明的命名空间,即那些奇怪的类似于网址的东西。重点关注其中可以看到应用资源中声明了一个叫做vm:ViewModelLocator的东西。

    前缀vm在上面可以看到是引入了命名空间,而且是位于我们的ViewModel文件夹下。

    这个Key=Locator的东西不知道怎么称呼,查字典叫做定位器。其实有点类似于公交总中心的意思。而这个资源的声明,对于我们后面的调用极其关键。

    我们打开这个ViewModelLocator类文件。它的代码如下所示,我也加上了自己的一些注释,应该可以简单理解。(我也说不很深入...)

        /// <summary>
        /// This class contains static references to all the view models in the
        /// application and provides an entry point for the bindings.
        /// <para>
        /// See http://www.mvvmlight.net
        /// </para>
        /// </summary>
        public class ViewModelLocator
        {
            public const string SecondPageKey = "SecondPage";
    
            /// <summary>
            /// This property can be used to force the application to run with design time data.
            /// </summary>
            public static bool UseDesignTimeData
            {
                get
                {
                    return false;
                }
            }
    
            static ViewModelLocator()
            {
                //设置一个简单IOC容器,放到ServiceLocator中(类似放东西到ServiceLocator仓库)
                ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
                //声明一个导航服务,MVVMLight封装的
                var nav = new NavigationService();
                //配置页面到导航服务中
                nav.Configure(SecondPageKey, typeof(SecondPage));
                //在IOC依赖注入容器中注册导航服务
                //一个是接口用来解耦用的,真实实例的是后面的我们配置的导航服务实例
                SimpleIoc.Default.Register<INavigationService>(() => nav);
    
                //同上,注册了对话框服务,这个也是MVVMLight封装的
                SimpleIoc.Default.Register<IDialogService, DialogService>();
    
                //上述都是一些常用的服务,我们一般都加上
                //如下是自己定义的数据服务,这个数据接口IDataService可以自己随意定义
                //然后注册入简单IOC容器中
                if (ViewModelBase.IsInDesignModeStatic
                        || UseDesignTimeData)
                {
                    SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
                }
                else
                {
                    SimpleIoc.Default.Register<IDataService, DataService>();
                }
    
                //最后,我们注册了页面相关的ViewModel
                SimpleIoc.Default.Register<MainViewModel>();
            }
    
            /// <summary>
            /// Gets the Main property.
            /// </summary>
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
                "CA1822:MarkMembersAsStatic",
                Justification = "This non-static member is needed for data binding purposes.")]
            //ServiceLocator中的Current属性存放的就是我们的简单IOC容器
            //当我们调用IOC容器的GetInstance方法时,IOC容器会自动组装实例返回给我们。
            //MainViewModel的构造函数不是无参的,而那些依赖的东西,IOC容器都帮我们在初始化时加入了进去。
            public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    

    今天就写到这里吧,之后还会再写后续的东西。现在想去玩其他的东西了,大家下回见面,2018还很漫长,希望大家今年也有更多的收获~~~
    谢谢了!!
    下一篇

    相关文章

      网友评论

        本文标题:MVVMLight的流程简单分析(二)

        本文链接:https://www.haomeiwen.com/subject/gpnynxtx.html