Xamarin.Forms 具有一个可用于存储数据的 Properties
字典,可使用 Application.Current.Properties
属性对其访问。 该字典使用 string
密钥并存储 object
值。 当应用暂停或关闭时,字典中的值将保存到设备,并在应用重新启动或从后台返回时加载。 有关属性字典的详细信息,请参阅属性字典。
在将在应用属性字典中存储数据的 Xamarin.Forms 应用迁移到 .NET MAUI 时,应当将此数据迁移到 .NET MAUI 首选项。 这可以通过本文中介绍的 LegacyApplication
类和帮助程序类实现。 此类可以让 Android、iOS 和 Windows 上的 .NET MAUI 应用从通过应用以前的 Xamarin.Forms 版本创建的应用属性字典读取数据。 有关 .NET MAUI 首选项的详细信息,请参阅 首选项。
重要说明
没有 API 可以访问 .NET MAUI 中的应用属性字典。
访问旧版应用属性数据
以下代码显示了 LegacyApplication
类,通过此类可以访问通过 Xamarin.Forms 应用创建的应用属性数据:
注意
要使用此代码,请将其添加到 .NET MAUI 应用项目中名为 LegacyApplication
的类。
namespace MigrationHelpers;
public class LegacyApplication
{
readonly PropertiesDeserializer deserializer;
Task<IDictionary<string, object>>? propertiesTask;
static LegacyApplication? current;
public static LegacyApplication? Current
{
get
{
current ??= (LegacyApplication)Activator.CreateInstance(typeof(LegacyApplication));
return current;
}
}
public LegacyApplication()
{
deserializer = new PropertiesDeserializer();
}
public IDictionary<string, object> Properties
{
get
{
propertiesTask ??= GetPropertiesAsync();
return propertiesTask.Result;
}
}
async Task<IDictionary<string, object>> GetPropertiesAsync()
{
IDictionary<string, object> properties = await deserializer.DeserializePropertiesAsync().ConfigureAwait(false);
properties ??= new Dictionary<string, object>(4);
return properties;
}
}
Android
在 Android 上,LegacyApplication
类使用 PropertiesDeserializer
类反序列化应用属性字典文件中的数据。 以下代码显示 PropertiesDeserializer
类:
注意
要使用此代码,请将其添加到 .NET MAUI 应用项目的 Platforms\Android 文件夹中名为 PropertiesDeserializer
的类。
using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;
using System.Xml;
namespace MigrationHelpers;
public class PropertiesDeserializer
{
const string PropertyStoreFile = "PropertyStore.forms";
public Task<IDictionary<string, object>> DeserializePropertiesAsync()
{
// Deserialize property dictionary to local storage
return Task.Run(() =>
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists(PropertyStoreFile))
return null;
using (IsolatedStorageFileStream stream = store.OpenFile(PropertyStoreFile, FileMode.Open, FileAccess.Read))
using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
{
if (stream.Length == 0)
return null;
try
{
var dcs = new DataContractSerializer(typeof(Dictionary<string, object>));
return (IDictionary<string, object>)dcs.ReadObject(reader);
}
catch (Exception e)
{
Debug.WriteLine("Could not deserialize properties: " + e.Message);
Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
}
}
}
return null;
});
}
}
iOS
在 iOS 上,LegacyApplication
类使用 PropertiesDeserializer
类反序列化应用属性字典文件中的数据。 以下代码显示 PropertiesDeserializer
类:
注意
要使用此代码,请将其添加到 .NET MAUI 应用项目的 Platforms\iOS 文件夹中名为 PropertiesDeserializer
的类。
using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;
using System.Xml;
namespace MigrationHelpers;
public class PropertiesDeserializer
{
const string PropertyStoreFile = "PropertyStore.forms";
public Task<IDictionary<string, object>> DeserializePropertiesAsync()
{
// Deserialize property dictionary to local storage
return Task.Run(() =>
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var stream = store.OpenFile(PropertyStoreFile, System.IO.FileMode.OpenOrCreate))
using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
{
if (stream.Length == 0)
return null;
try
{
var dcs = new DataContractSerializer(typeof(Dictionary<string, object>));
return (IDictionary<string, object>)dcs.ReadObject(reader);
}
catch (Exception e)
{
Debug.WriteLine("Could not deserialize properties: " + e.Message);
Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
}
}
return null;
});
}
}
Windows
在 Windows 上,LegacyApplication
类使用 PropertiesDeserializer
类反序列化应用属性字典文件中的数据。 以下代码显示 PropertiesDeserializer
类:
注意
要使用此代码,请将其添加到 .NET MAUI 应用项目的 Platforms\Windows 文件夹中名为 PropertiesDeserializer
的类。
using System.Diagnostics;
using System.Runtime.Serialization;
using Windows.Storage;
namespace MigrationHelpers;
public class PropertiesDeserializer
{
const string PropertyStoreFile = "PropertyStore.forms";
public async Task<IDictionary<string, object>> DeserializePropertiesAsync()
{
try
{
StorageFile file = await ApplicationData.Current.RoamingFolder.GetFileAsync(PropertyStoreFile).DontSync();
using (Stream stream = (await file.OpenReadAsync().DontSync()).AsStreamForRead())
{
if (stream.Length == 0)
return new Dictionary<string, object>(4);
try
{
var serializer = new DataContractSerializer(typeof(IDictionary<string, object>));
return (IDictionary<string, object>)serializer.ReadObject(stream);
}
catch (Exception e)
{
Debug.WriteLine("Could not deserialize properties: " + e.Message);
Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
}
return null;
}
}
catch (FileNotFoundException)
{
return new Dictionary<string, object>(4);
}
}
}
PropertiesDeserializer
类的此 Windows 版本需要使用 DontSync
扩展方法。 下面代码展示了此扩展方法:
注意
要使用此代码,请将其添加到 .NET MAUI 应用项目 Platforms\Windows 文件夹中名为 Extensions
的类。
using System.Runtime.CompilerServices;
using Windows.Foundation;
namespace MigrationHelpers;
internal static class Extensions
{
public static ConfiguredTaskAwaitable<T> DontSync<T>(this IAsyncOperation<T> self)
{
return self.AsTask().ConfigureAwait(false);
}
}
使用旧版应用属性数据
LegacyApplication
类可用于使用 Android、iOS 和 Windows 上通过应用以前的 Xamarin.Forms 版本创建的应用属性字典中的数据:
#if ANDROID || IOS || WINDOWS
using MigrationHelpers;
...
int id;
if (LegacyApplication.Current.Properties.ContainsKey("id"))
{
id = (int)LegacyApplication.Current.Properties["id"];
Preferences.Set("id", id);
}
#endif
此示例展示如何使用 LegacyApplication
类从应用属性字典中读取值,然后将该值写入 .NET MAUI 首选项。
重要说明
请务必首先检查应用属性字典中是否存在密钥,然后再访问它,以防止发生意外错误。