將數據從 Xamarin.Forms 應用程式屬性字典遷移至 .NET MAUI 喜好設定
Xamarin.Forms 有一個 Properties
字典,可用來儲存數據,並使用 屬性來存取 Application.Current.Properties
。 此字典使用 string
索引鍵並儲存 object
值。 字典中的值會在應用程式暫停或關閉時儲存至裝置,並在應用程式重新啟動或從背景傳回時載入。 如需屬性字典的詳細資訊,請參閱 屬性字典。
將 Xamarin.Forms 應用程式將資料儲存在應用程式屬性字典中的 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 應用程式專案的 Platform\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 應用程式專案的 Platform\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 應用程式專案的 Platform\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);
}
}
}
這個 Windows 版本的 PropertiesDeserializer
類別需要 DontSync
擴充方法。 下列程式代碼顯示此擴充方法:
注意
若要使用此程式碼,請將它新增至 .NET MAUI 應用程式專案的 Platform\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 喜好設定。
重要
請務必先檢查應用程式屬性字典中是否有索引鍵,再存取它,以避免發生非預期的錯誤。