在开始装逼之前,老周先说明一件事。有人说老周写的东西太简单了,能不能写点复杂点。这问题就来了,要写什么东西才叫 "复杂"?最重要的是,写得太复杂了,一方面很多朋友看不懂,另一方面,连老周自己也不知道怎么表述。
而且,老周也不能把以前在 K 公司、Z 公司和 T 公司中做项目的东西写出来的,其实嘛,工作中的编程没什么可写的,无非就是 select、insert、delete、update,无非就是连接数据库,断开连接,同步一下数据,把数据变成 XML 或 JSON 再发给另一终端。无非就是读读你的网卡 CPU 硬盘序列号,组成个东东再加密,计算一下授权码,又或者生成个假冒伪劣证书给用户授授权。再不是就写几个 API 给别人调几下。让脑细胞死亡率大增的,就是要动态生成计算工资的公式,这个嘛,当时老周是选用 Code Dom 来生成的,代码生成这玩意儿,老周前些时间就写过好些博文了,相信大伙伴们也看过了。
所以,你看,工作中用到的东西其实很片面很单一,所覆盖的面还不如老周平时闲着没事的时候写的小程序。故,还是写点简单的东西和谐一点,你懂我懂他也懂,岂不甚妙,人活着为啥老跟自己过不去呢,姜育恒大哥就曾经唱过:
平淡是福,简单是乐,谁谓不然?
好了,上面的鬼话说完了,下面咱们开始说人话。
我们都知道,VS 开发环境会为项目自动生成一个 settings 类,即用于访问应用程序设置的帮助类,数据是存到跟应用程序一起的 config 文件中,比如历史上著名的 App.config 文件。
顺便提一下,VS 自动生成的应用设置类有一个特点:基于应用程序范围的设置项是只读的,基于用户范围的设置项是可读可写的。看不懂?没事,你可以动手调戏一下这个 settings 类的。
在 Properties 节点下,你应该能看到一个 Settings 文件,然后打开它。
这里你可以自己添加设置项,注意看 "范围" 这一列,它就两个选项,要么是基于应用范围,要么基于用户范围。好,我们为每个范围各添加一个设置项。
随后,我们保存一下(必须,保存才会生成代码),接着打开代码,看看设计器生成的 Settings 类。
代码选段。
- [global: :System.Configuration.UserScopedSettingAttribute()][global: :System.Diagnostics.DebuggerNonUserCodeAttribute()][global: :System.Configuration.DefaultSettingValueAttribute("0")] public byte TestV1 {
- get {
- return ((byte)(this["TestV1"]));
- }
- set {
- this["TestV1"] = value;
- }
- }
- [global: :System.Configuration.ApplicationScopedSettingAttribute()][global: :System.Diagnostics.DebuggerNonUserCodeAttribute()][global: :System.Configuration.DefaultSettingValueAttribute("0")] public int TestV2 {
- get {
- return ((int)(this["TestV2"]));
- }
- }
在属性上应用 ApplicationScopedSettingAttribute 表示该设置项是应用程序范围的,大伙看到,属性中只有 get 没有 set,说明它是只读的。而应用了 UserScopedSettingAttribute 的属性表示的是用户范围内的设置项,此时看到该属性同时有 get 和 set ,即可读可写。
为什么应用程序范围的设置项相关属性会生成只读属性呢,后来一看 MSDN 就明白了,因为当调用相关方法保存设置时,应用程序范围内的设置是不会起作用的,但是不会报错。也就是说,要自己写可以直接保存的设置项,只能把属性定义为用户范围内的。
如果觉得生成的设置类不好玩,我们可以自己写的。
编写这个类其实很简单,我们只需从 ApplicationSettingsBase 类派生即可,该类位于 System.Configuration 命名空间下,它是一个抽象类。在写自定义的应用设置类时,我们可以像普通类一样公开属性,这样读写设置项时也方便,而且,你还可以直接用于数据绑定。
在包装属性时,是通过调用基类的索引器来存取内容的,它是一个字典模型,key 是字符串类型,而 value 是 Object 类型,这样你可以设置各种类型的值。
好,咱们写一个来表演一下。
- internal class AppSettings: ApplicationSettingsBase {#region常量const string APP_TITLE = "appTitle";
- const string APP_USAGE = "appUsage";
- const string USER_NAME = "userName";
- const string USE_YEARS = "useYears";#endregion
- [UserScopedSetting][DefaultSettingValue("my app")] public string AppTitle {
- set {
- this[APP_TITLE] = value;
- }
- get {
- return (string) this[APP_TITLE];
- }
- }
- [UserScopedSetting][DefaultSettingValue("用于装X")] public string AppUsage {
- get {
- return (string) this[APP_USAGE];
- }
- set {
- this[APP_USAGE] = value;
- }
- }
- [UserScopedSetting][DefaultSettingValue("大傻冬")] public string UserName {
- get {
- return (string) this[USER_NAME];
- }
- set {
- this[USER_NAME] = value;
- }
- }
- [UserScopedSetting][DefaultSettingValue("3")] public int UseYears {
- get {
- return (int) this[USE_YEARS];
- }
- set {
- this[USE_YEARS] = value;
- }
- }
- }
由于属性实现中使用的 key 是字符串类型的,为了防止多次输入时出现错误,通常可以预先声明一组字符串常量。
- const string APP_TITLE = "appTitle";
- const string APP_USAGE = "appUsage";
- const string USER_NAME = "userName";
- const string USE_YEARS = "useYears";
在类公开的属性上除了应用表示用户范围内的标识特性外,还应用了 DefaultSettingValue 特性,它用来设置项的默认值,值是以字符串形式表示的。
这个示范的设置类包装了四个设置项,那么,怎么耍呢。耍起来也很简单,跟耍猴差不多。首先,你要 new 一个类实例,接着就可以通过我们刚才包装的那四个属性来读写设置项,最后,调用 Save 方法,就可以把修改后的数据保存到配置文件中。
让设置类与用户界面交互,最简单最方便的方法是使用绑定,比如这样。
- "1"Text = "{Binding Path=AppTitle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" / >"1"Grid.Row = "1"Text = "{Binding Path=AppUsage,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" / >"1"Grid.Row = "2"Text = "{Binding Path=UserName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" / >"1"Grid.Row = "3"Text = "{Binding Path=UseYears,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" / >
这个设置类是可以进行双向绑定的,因为基类 ApplicationSettingsBase 实现了 INotifyPropertyChanged 接口。通常我们可以在窗口关闭时保存配置。
- protected override void OnClosing(CancelEventArgs e) {
- base.OnClosing(e);
- settings.Save();
- }
以前我们开发程序,都习惯在界面上放一个保存按钮,当用户点击后保存,不过现在好像流行了,因为用户修改完设置后还要点一按钮来保存,操作有点复杂,让窗口在关闭时自动保存设置,显得更友好。
那么,这个破文件到底保存到哪里去了,在应用所在目录中的配置文件中并没有。应用目录中的配置文件存的应用程序级别的设置,用户级别的配置应该与当前用户的私人目录有关。
打开文件管理器,在地址栏中输入:%UserProfile%\AppData\Local,然后回车,就会进入当前用户文件夹下的 appData 的 Local 子目录,然后,在这个目录下,你会看到一个以你的应用程序命名的文件夹,然后你继续进入子目录,直到看到一个名为 user.config 的文件。对,就是它了,不信你打开看看。
- <configuration>
- <configSections>
- <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
- <section name="DemoApp.AppSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- allowExeDefinition="MachineToLocalUser" requirePermission="false" />
- </sectionGroup>
- </configSections>
- <userSettings>
- <DemoApp.AppSettings>
- <setting name="UseYears" serializeAs="String">
- <value>
- 2
- </value>
- </setting>
- <setting name="UserName" serializeAs="String">
- <value>
- 矮冬瓜
- </value>
- </setting>
- <setting name="AppUsage" serializeAs="String">
- <value>
- 用于忽悠未成年人
- </value>
- </setting>
- <setting name="AppTitle" serializeAs="String">
- <value>
- 天国第一假货
- </value>
- </setting>
- </DemoApp.AppSettings>
- </userSettings>
- </configuration>
另外,ApplicationSettingsBase 类有几个事件比较有用,必要时可以用上。当设置数加载后会发生 SettingsLoaded 事件,从名字中也能知道其用途;在设置项被修改之前,会发生 SettingChanging 事件,修改之后会发生 PropertyChanged 事件(实现了 INotifyPropertyChanged 接口);当调用 Save 方法保存之前,会引发 SettingsSaving 事件,事件参数会包含一个 Cancel 属性,如果想取消保存,可以将该属性设置为 true。
示例源代码下载地址:请点击▶这里◀
来源: http://www.cnblogs.com/tcjiaan/p/7227861.html