天天看点

艾伟:WM有约(二):配置信息

Written by Allen Lee

添加配置文件

首先,向项目添加一个Options.xml文件,这个文件将会用来储存应用程序的配置信息:

艾伟:WM有约(二):配置信息

图 1

接着,把Options.xml的Copy to Output Directory属性的值改为Copy if newer:

艾伟:WM有约(二):配置信息

图 2

然后,就是为Options.xml添加配置信息了:

艾伟:WM有约(二):配置信息

代码 1

那么,我们如何使用这个文件呢?关于这个问题,我首先想到的是为它创建一个OptionManager类,在我的想象里,它应该是这样使用的:

艾伟:WM有约(二):配置信息

代码 2

在继续之前,我想请你思考一个问题:你会如何实现OptionManager的Options成员呢?下面是我的做法,使用了单例模式和索引器:

艾伟:WM有约(二):配置信息

代码 3

当然,你也可以学ConfigurationManager类那样,通过AppSettings静态属性返回一个NameValueCollection对象。接下来的问题是,如何访问Options.xml呢?由于Options.xml上面的配置信息实际上只是一组键/值对,于是你可以考虑在OptionManager的构造函数里把它们全部读到一个内部的Dictionary对象里:

艾伟:WM有约(二):配置信息

代码 4

LoadOptions方法使用了LINQ to XML来读取Options.xml里的配置信息,并以Dictionary的形式返回:

艾伟:WM有约(二):配置信息

代码 5

这里使用了GetXmlPath方法来获取Options.xml的路径:

艾伟:WM有约(二):配置信息

代码 6

OptionManager提供了一个Save方法,用于保存配置信息:

艾伟:WM有约(二):配置信息

代码 7

其中,SaveOptions方法也使用了LINQ to XML来构建并保存配置信息:

艾伟:WM有约(二):配置信息

代码 8

最后就是OptionManager的索引器了:

艾伟:WM有约(二):配置信息

代码 9

设计选项窗体

说到选项窗体,你会如何设计?我想象中的选项窗体大致像这样:

艾伟:WM有约(二):配置信息

图 3

我用了一个NumericUpDown控件来收集MaxSelectionCount的配置信息,另外用了两个DateTimePicker控件分别收集MinDate和MaxDate的配置信息。

接着,我们来看看底下两个菜单项。Cancel菜单项比较简单,仅仅把窗体的DialogResult设为Cancel:

艾伟:WM有约(二):配置信息

代码 10

而OK菜单项的任务就多一点,它要保存用户的配置信息:

艾伟:WM有约(二):配置信息

代码 11

接着就是修改一下主窗体的菜单:

艾伟:WM有约(二):配置信息

图 4

Save菜单项和以前一样,而Options菜单项将会打开选项窗体:

艾伟:WM有约(二):配置信息

代码 12

现在,我们来运行一下这个应用程序:

艾伟:WM有约(二):配置信息

图 5

艾伟:WM有约(二):配置信息

图 6

有问题!选项窗体打开的时候,上面的控件没有反映配置文件里面的信息,这是因为我没有实现这样的逻辑,同样地,这个问题也会发生在主窗体身上,这意味着无论我们如何修改配置文件,重新启动应用程序之后,主窗体将会恢复默认配置,何等严重!

首先是选项窗体打开的时候需要读取配置信息到对应的控件上:

艾伟:WM有约(二):配置信息

代码 13

艾伟:WM有约(二):配置信息

代码 14

由于读取配置信息的代码和代码12里的那部分是相同的,所以我把它提取出来,放在SetupOptions方法里,这样,代码12就简化为:

艾伟:WM有约(二):配置信息

代码 15

再次运行应用程序:

艾伟:WM有约(二):配置信息

图 7

这次正常了。不过还有一个小问题,选项窗体里保存配置信息的代码属于OK菜单项而不是选项窗体的,当用户单击窗体右上角的OK按钮时,虽然窗体的DialogResult属性返回OK,但实质上没有执行任何保存配置信息的操作,这就导致了窗体行为的不一致。解决这个问题的办法有两个,一个是去掉窗体右上角的OK按钮,另一个是把OK菜单项里保存配置信息的代码放到窗体层面上做。前一种做法很简单,只需要把选项窗体的ControlBox属性设为false就行了。至于后一种做法,在继续讨论之前,我想先考一考你,我应该选择Deactivate事件还是Closing事件呢?答案是两个都可以,因为选项窗体是通过ShowDialog方法打开的,关闭这样的窗体是真的关闭了而不是像主窗体那样最小化到后台,所以我们可以放胆使用Closing事件:

艾伟:WM有约(二):配置信息

代码 16

还有一个不是问题的问题,就是当你关闭选项窗体时,你会发现画面突然停顿,你知道这个时候OptionManager在保存配置信息,但用户并不知道,这可能会给用户留下不好的印象/感受,要让用户知道后台正在执行任务,最简单的办法就是在屏幕正中显示等待指针,当然,任务完成之后记得去掉等待指针,否则……

你还想要什么?

下一集,除了上一集剩下的两个需求之外,我们还会探讨两个新的需求:

支持日期的包含,比如说2009年2月14日被指定为届时要选的日期。

如果指定一个周期,应用程序将会综合排除逻辑、包含逻辑和这个周期计算下一个将要被选中的日期,并显示在主界面上。

继续阅读