时间过得可真快,转眼就2018年了。
2018年的第一篇文章,就继续简单讲一下mvvmlight的整个应用启动的那些部分,为了避免自己忘记。
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
文件中。而在那里,声明了很重要的东西。我们接着往下看。
这是一个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还很漫长,希望大家今年也有更多的收获~~~
谢谢了!!
下一篇