配置容器和设置持久化
在软件关闭时存储设置是每一个软件必需的功能。在WPF中可以通过Settings.settings文件指定,但设置存储的位置很难确定,这不是一个好方法。
在WinUI 3里也有一套自带的设置系统,我们可以方便地使用它来存储用户自定义的设置。
新版变化
WASDK1.6中,更新了Microsoft.Windows.Storage.ApplicationDataContainer
API,以取代从旧版UWP继承来的Windows.Storage.ApplicationDataContainer
。
区别在于Microsoft.*
命名空间下的API较新,而且支持非打包应用。
而且新的ApplicationDataContainer
API不支持漫游设置,这是由于Win11不支持了(所以旧版的API支持也是有名无实了),MSDN建议使用Azure 应用服务代替。
支持数据类型
根据MSDN,设置中可以有一下类型:
- 基元类型(注意没有
sbyte
):byte
、short
、ushort
、int
、uint
、long
、ulong
、float
、double
、bool
、char
、string
- 时间类型(注意没有
System.DateTime
):System.DateTimeOffset
、System.TimeSpan
- 其他结构体:
GUID
、Point
、Size
、Rect
- 集合结构:
ApplicationDataCompositeValue
其中ApplicationDataCompositeValue
是一个设置值的键值对集合,键值对的值可以包含以上允许的类型,也就是说可以用这个递归地定义设置内容。
注意读取时得到的是object
类型,需要进行类型转换。
若不存在对应值会返回null
而不是抛出异常。
// 创建ApplicationDataCompositeValue
var composite = new Windows.Storage.ApplicationDataCompositeValue();
// 写入或修改
composite["intVal"] = 1;
composite["strVal"] = "string";
// 读取
var a = (int)composite["intVal"];
var b = (string)composite["strVal"];
var c = composite["strVal2"]; // null
// 删除
_ = composite.Remove("intVal");
使用ApplicationDataContainer
获取默认容器
ApplicationData里包含一个LocalSettings
实例属性,表示本地配置容器。这个容器可以直接使用。
using Microsoft.Windows.Storage;
ApplicationData applicationData = ApplicationData.GetDefault();
ApplicationDataContainer localSettings = applicationData.LocalSettings;
读取和写入
ApplicationDataContainer
和ApplicationDataCompositeValue
的处理类似:
注意读取时得到的是object
类型,需要进行类型转换。
若不存在对应值会返回null
而不是抛出异常。
using Windows.Foundation.Collections;
// 获取
IPropertySet values = localSettings.Values;
// 写入
values["intVal"] = 1;
values["strVal"] = "string";
// 读取
var a = (int)values["intVal"];
var b = (string)values["strVal"];
var c = values["strVal2"]; // null
// 删除
_ = values.Remove("intVal");
子容器
有些读者可能也发现了,容器中有创建、删除、获取容器的方法,这说明容器可以包含容器。
说明除了ApplicationDataCompositeValue
,也可以用容器实现多层结构。
但由于不能直接构造ApplicationDataContainer
,所以子容器树的根一定是LocalSettings
using System.Collections.Generic;
using Microsoft.Windows.Storage;
// 创建
ApplicationDataContainer subContainer = localSettings.CreateContainer("exampleKey", ApplicationDataCreateDisposition.Always);
// 删除
ApplicationDataContainer subContainer = localSettings.DeleteContainer("exampleKey");
// 更多操作
IDictionary<string, ApplicationDataContainer> containers = localSettings.Containers;
[!NOTE]
此处CreateContainer
的第二个参数ApplicationDataCreateDisposition
,枚举有Always
和Existing
两个值。
- 指定为
Always
时,若存在指定键的容器,直接返回该容器;若不存在,则创建一个新的并返回。- 指定为
Existing
,若存在指定键的容器,直接返回该容器;若不存在,则抛出异常。由此看出
CreateContainer
的“Create”其实是创建“Container”这个对象的意思,而不是在设置里创建一个对应“Container”的意思。
磁盘上的设置文件
当对Values
或Containers
的执行一旦结束,设置就会被立即保存,并保存到硬盘上,保存的位置在:
%LOCALAPPDATA%\Packages\<项目标识符>\Settings\settings.dat
展开形式:
C:\Users\<用户名>\AppData\Local\Packages\<项目标识符>\Settings\settings.dat