1、DataChangedEvent
对于保存在云端的设置或者文件,应用程序需要知道什么时间数据发生了变化从而更改对应的用户 UI。在任何时间当云端的处理(handler)被触发时会同步触发 datachanged 事件。
这个示例将响应 datachanged 事件,并且更新 UI。
在两台登录的微软账号的机器上同时运行本示例会看到当云端的设置更新时,会同步更改该程序的 UI。
ApplicationData applicationData = ApplicationData.Current; // 提供对与应用程序的应用程序包相关的应用程序数据存储的访问。 ApplicationDataContainer roamingSettings = applicationData.RoamingSettings; //获取漫游应用程序数据存储区中的应用程序设置容器。 const string settingName = "userName"; applicationData.DataChanged += new TypedEventHandler<ApplicationData, object>(DataChangedHandler); // 在同步漫游应用程序数据时发生。
async void DataChangedHandler(Windows.Storage.ApplicationData appData, object o) { //当触发 DataChanged 事件时调用 // DataChangeHandler may be invoked on a background thread, so use the Dispatcher to invoke the UI-related code on the UI thread. await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { Object value = roamingSettings.Values[settingName]; OutputTextBlock.Text = "Name: " + (value == null ? "<empty>" : ("\"" + value + "\"")); }); }
roamingSettings.Values[settingName] = UserName.Text; // Simulate roaming by intentionally signaling a data changed event. 向所有已注册的事件处理程序发送数据更改事件。 applicationData.SignalDataChanged();
2、RoamingL: HighPrority
如果需要在不同的设备之间进行比较时间紧迫的设置通信,可以使用 高优先级的设置(HighPriority setting)。这种方法使用于用户的环境信息(context)(例如:游戏的等级、用户看书的页码等)
当使用这种设置时,设置为 “HighPriority”,操作系统就会自动的频繁响应云端数据设置。这个 HighPriority 设置可以是一个复合的设置。
本示例演示了向 HighPriority setting 中写入,并且响应当云端数据进来触发 datachanged 事件。在两台机器上运行这个示例使用相同的连接帐户观察漫游设置。
导读:向 HighPriority setting 写数据可以使开发者把少量数据比其他漫游数据有更高优先级的被存储到云端。
应该仔细权衡应用程序的哪些数据应该使用 HighPriority setting。“Context” 数据 例如用户的媒体内的位置信息
或者他们的游戏排行榜、得分可以优先设置为 highPriority。通过 highPriority 设置,这些信息享有更高的可能性被分享
到用户所使用的其它机器中。
应用程序应该在用户更改数据时更新他们的 highPriority 设置。包括例如用户音乐的状态、在书中的页码或者完成游戏中的一个任务。
ApplicationData applicationData = ApplicationData.Current; //提供对与应用程序的应用程序包相关的应用程序数据存储的访问。 ApplicationDataContainer roamingSettings = applicationData.RoamingSettings; // 获取漫游应用程序数据存储区中的应用程序设置容器。 applicationData.DataChanged += new TypedEventHandler<ApplicationData, object>(DataChangedHandler); // 在同步漫游应用程序数据时发生。
async void DataChangedHandler(Windows.Storage.ApplicationData appData, object o) { // DataChangeHandler may be invoked on a background thread, so use the Dispatcher to invoke the UI-related code on the UI thread. await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { int counter = Convert.ToInt32(roamingSettings.Values["HighPriority"]); OutputTextBlock.Text = "Counter: " + counter + "(updated remotely)" ; }); }
int counter = Convert.ToInt32(roamingSettings.Values["HighPriority"]); //获取并增加 HighPriority 对应的值 roamingSettings.Values["HighPriority"] = counter + 1;
3、ms-appdata://Protocol
可以使用 ms-appdata:// protocol 的方式来访问应用程序文件夹中的 媒体(图片、声音、视频)。这个示例展示了从本地、云端和 临时文件夹中加载图片。
ApplicationData appData = ApplicationData.Current; // 提供对与应用程序的应用程序包相关的应用程序数据存储的访问。 try { StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///assets/appDataLocal.png")); //异步获取应用程序中的文件 await sourceFile.CopyAsync(appData.LocalFolder); // 在本地应用程序数据存储区中的根文件夹中创建文件的副本。当此方法成功完成时,它将返回表示副本的 StorageFile } catch (Exception) { // If the image has already been copied the CopyAsync() method above will fail. // Ignore this error. } try { StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///assets/appDataRoaming.png")); await sourceFile.CopyAsync(appData.RoamingFolder); // 在漫游应用程序数据存储区中的根文件夹中创建文件的副本。 } catch (Exception) { // If the image has already been copied the CopyAsync() method above will fail. // Ignore this error. } try { StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///assets/appDataTemp.png")); await sourceFile.CopyAsync(appData.TemporaryFolder); //在临时应用程序数据存储区中的根文件夹中创建文件的副本。 } catch (Exception) { // If the image has already been copied the CopyAsync() method above will fail. // Ignore this error. } LocalImage.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appdata:///local/appDataLocal.png")); //本地的 RoamingImage.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appdata:///roaming/appDataRoaming.png"));//漫游的 TempImage.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appdata:///temp/appDataTemp.png"));//临时的 }
4、clear:
使用 Windows.Storage.ApplicationData.Current.ClearAsync 方法来清除 ApplicationData 中的数据。
async void Clear_Click(Object sender, RoutedEventArgs e) { try { await Windows.Storage.ApplicationData.Current.ClearAsync(); OutputTextBlock.Text = "ApplicationData has been cleared. Visit the other scenarios to see that their data has been cleared."; } catch (Exception) { OutputTextBlock.Text = "Unable to clear settings. This can happen when files are in use."; } }
5、SetVersion:
版本控制可以使你在以后版本的应用程序中改变应用程序数据格式,而不会引起和之前版本的冲突。每个版本只会漫游到相同的版本,从而分离不兼容的数据。使用 Windows.Storage.ApplicationData.Current.SetVersion 来改变 ApplicationData 的版本。
// SetVerion 页面类中的成员 public sealed partial class SetVersion : Page { ApplicationData appData = null; const string settingName = "SetVersionSetting"; const string settingValue0 = "Data.v0"; const string settingValue1 = "Data.v1"; public SetVersion() { this.InitializeComponent(); appData = ApplicationData.Current; //提供对与应用程序的应用程序包相关的应用程序数据存储的访问。 DisplayOutput(); } // SetVersionRequest : 当应用程序在其应用程序数据存储中设置应用程序数据的版本时提供数据。 void SetVersionHandler0(SetVersionRequest request) { SetVersionDeferral deferral = request.GetDeferral(); // 请求延迟集版本请求。 uint version = appData.Version; // 获取应用程序数据存储区中的应用程序数据的版本号。 switch (version) { case 0: // Version is already 0. Nothing to do. break; case 1: // Need to convert data from v1 to v0. // This sample simulates that conversion by writing a version-specific value. appData.LocalSettings.Values[settingName] = settingValue0; break; default: throw new Exception("Unexpected ApplicationData Version: " + version); } deferral.Complete(); // 通知系统应用程序已在其应用程序数据存储区设置应用程序数据的版本。 } void SetVersionHandler1(SetVersionRequest request) { SetVersionDeferral deferral = request.GetDeferral(); uint version = appData.Version; switch (version) { case 0: // Need to convert data from v0 to v1. // This sample simulates that conversion by writing a version-specific value. appData.LocalSettings.Values[settingName] = settingValue1; break; case 1: // Version is already 1. Nothing to do. break; default: throw new Exception("Unexpected ApplicationData Version: " + version); } deferral.Complete(); } async void SetVersion0_Click(Object sender, RoutedEventArgs e) { await appData.SetVersionAsync(0, new ApplicationDataSetVersionHandler(SetVersionHandler0)); // 设置应用程序数据存储区中的应用程序数据的版本号。 DisplayOutput(); } async void SetVersion1_Click(Object sender, RoutedEventArgs e) { await appData.SetVersionAsync(1, new ApplicationDataSetVersionHandler(SetVersionHandler1)); DisplayOutput(); } void DisplayOutput() { OutputTextBlock.Text = "Version: " + appData.Version; }