選取器: CachedFileUpdater(緩存文件更新程序)
介紹
重新想象 Windows 8 Store Apps 之 選取器
CachedFileUpdater - 緩存文件更新程序
示例
一、首先新建一個 Windows 應用商店項目,使其作為緩存文件更新程序
1、 打開一個文件,並關 聯到 CachedFileUpdater
CachedFileUpdaterProvider/MyOpenPicker.xaml
<Page
x:Class="CachedFileUpdaterProvider.MyOpenPicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CachedFileUpdaterProvider"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<TextBlock Name="lblMsg" FontSize="14.667" />
<Button Name="btnPickCachedFileLocal" Content="提供一個由 Local 更新的 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnPickCachedFileLocal_Click_1" Margin="0 10 0
0" />
<Button Name="btnPickCachedFileRemote" Content="提供一個由 Remote 更新的 CachedFile(由 app 更新 CachedFile)" Click="btnPickCachedFileRemote_Click_1" Margin="0 10 0 0"
/>
</StackPanel>
</Grid>
</Page>
CachedFileUpdaterProvider/MyOpenPicker.xaml.cs
/*
* 打開一個文件,並關聯到 CachedFileUpdater
*
* 1、在 Package.appxmanifest 中新增一個“文件打開選取器”聲明,並做相關配置
* 2、在 App.xaml.cs 中 override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args),如果 app 是由文件打開選取器激活的,則可以在此獲取其相關信息
*/
using System;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Pickers.Provider;
using Windows.Storage.Provider;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace CachedFileUpdaterProvider
{
public sealed partial class MyOpenPicker : Page
{
private FileOpenPickerUI _fileOpenPickerUI;
public MyOpenPicker()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var args = (FileOpenPickerActivatedEventArgs)e.Parameter;
_fileOpenPickerUI = args.FileOpenPickerUI;
_fileOpenPickerUI.Title = "自定義文件打開選取器";
}
// 本 CachedFile 用於從 Local 更新
private async void btnPickCachedFileLocal_Click_1(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdCachedFileUpdaterLocal.txt", CreationCollisionOption.ReplaceExisting);
string textContent = "I am webabcd";
await FileIO.WriteTextAsync(file, textContent);
/*
* 設置 CachedFile,即將文件關聯到 CachedFileUpdater
* SetUpdateInformation(IStorageFile file, string contentId, ReadActivationMode readMode, WriteActivationMode writeMode, CachedFileOptions options);
* file - 與 CachedFileUpdater 關聯的文件
* contentId - 與 CachedFileUpdater 關聯的文件標識
*/
CachedFileUpdater.SetUpdateInformation(file, "cachedFileLocal", ReadActivationMode.BeforeAccess, WriteActivationMode.NotNeeded, CachedFileOptions.RequireUpdateOnAccess);
lblMsg.Text = "選擇的文件: " + file.Name;
AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
}
// 本 CachedFile 用於從 Remote 更新
private async void btnPickCachedFileRemote_Click_1(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdCachedFileUpdaterRemote.txt", CreationCollisionOption.ReplaceExisting);
string textContent = "I am webabcd";
await FileIO.WriteTextAsync(file, textContent);
/*
* 設置 CachedFile,即將文件關聯到 CachedFileUpdater
* SetUpdateInformation(IStorageFile file, string contentId, ReadActivationMode readMode, WriteActivationMode writeMode, CachedFileOptions options);
* file - 與 CachedFileUpdater 關聯的文件
* contentId - 與 CachedFileUpdater 關聯的文件標識
*/
CachedFileUpdater.SetUpdateInformation(file, "cachedFileRemote", ReadActivationMode.NotNeeded, WriteActivationMode.AfterWrite, CachedFileOptions.RequireUpdateOnAccess);
lblMsg.Text = "選擇的文件: " + file.Name;
AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
}
}
}
2、 開發自定義緩存文件更新程序
CachedFileUpdaterProvider/MyCachedFileUpdater.xaml
<Page
x:Class="CachedFileUpdaterProvider.MyCachedFileUpdater"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CachedFileUpdaterProvider"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<TextBlock Name="lblMsg" FontSize="14.667" />
<Button Name="btnUpdate" Content="更新 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnUpdate_Click_1" Margin="0 10 0 0" />
</StackPanel>
</Grid>
</Page>
CachedFileUpdaterProvider/MyCachedFileUpdater.xaml.cs
/*
* 演示如何開發自定義緩存文件更新程序
*
* 1、在 Package.appxmanifest 中新增一個“緩存文件更新程序”聲明,並做相關配置
* 2、在 App.xaml.cs 中 override void OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args),如果 app 是由文件打開選取器激活的,則可以在此獲取其相關信息
*
* CachedFileUpdaterActivatedEventArgs - 通過“緩存文件更新程序”激活應用程序時的事件參數
* CachedFileUpdaterUI - 獲取 CachedFileUpdaterUI 對象
* PreviousExecutionState, Kind, SplashScreen - 各種激活 app 的方式的事件參數基
*
* CachedFileUpdaterUI - 緩存文件更新程序的幫助類
* Title - 將在“緩存文件更新程序”上顯示的標題
* UIStatus - “緩存文件更新程序”的 UI 狀態(Unavailable, Hidden, Visible, Complete)
* UpdateTarget - Local 代表由 CachedFileUpdater 更新; Remote 代表由 app 更新
* UIRequested - 需要顯示“緩存文件更新程序”的 UI 時觸發的事件
* FileUpdateRequested - 當 app 激活緩存文件更新程序時,會觸發 FileUpdateRequested 事件(事件參數:CachedFileUpdaterActivatedEventArgs)
*
* CachedFileUpdaterActivatedEventArgs
* Request - 返回 FileUpdateRequest 類型的對象
*
* FileUpdateRequest
* File - 關聯的文件
* ContentId - 關聯的文件標識
* Status - 文件的更新狀態(FileUpdateStatus 枚舉。Incomplete, Complete, UserInputNeeded, CurrentlyUnavailable, Failed, CompleteAndRenamed)
* GetDeferral() - 獲取異步操作對象,同時開始異步操作,之後通過 Complete() 通知完成異步操作
*/
using System;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Provider;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace CachedFileUpdaterProvider
{
public sealed partial class MyCachedFileUpdater : Page
{
private CachedFileUpdaterUI _cachedFileUpdaterUI;
private FileUpdateRequest _fileUpdateRequest;
private CoreDispatcher _dispatcher = Windows.UI.Xaml.Window.Current.Dispatcher;
public MyCachedFileUpdater()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 獲取 CachedFileUpdaterUI 對象
var args = (CachedFileUpdaterActivatedEventArgs)e.Parameter;
_cachedFileUpdaterUI = args.CachedFileUpdaterUI;
_cachedFileUpdaterUI.Title = "緩存文件更新程序";
_cachedFileUpdaterUI.FileUpdateRequested += _cachedFileUpdaterUI_FileUpdateRequested;
_cachedFileUpdaterUI.UIRequested += _cachedFileUpdaterUI_UIRequested;
}
// 需要顯示 CachedFileUpdater 的 UI 時(即當 FileUpdateRequest.Status 等於 UserInputNeeded 時),會調用此事件處理器
async void _cachedFileUpdaterUI_UIRequested(CachedFileUpdaterUI sender, object args)
{
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
Windows.UI.Xaml.Window.Current.Content = this;
lblMsg.Text = "FileUpdateStatus: " + _fileUpdateRequest.Status.ToString();
});
}
void _cachedFileUpdaterUI_FileUpdateRequested(CachedFileUpdaterUI sender, FileUpdateRequestedEventArgs args)
{
_fileUpdateRequest = args.Request;
FileUpdateRequestDeferral fileUpdateRequestDeferral = _fileUpdateRequest.GetDeferral();
if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Local) // 由 CachedFileUpdater 更新 CachedFile(CachedFileTarget.Local 方式)
{
// 顯示 CachedFileUpdater 的 UI
if (_cachedFileUpdaterUI.UIStatus == UIStatus.Hidden)
{
_fileUpdateRequest.Status = FileUpdateStatus.UserInputNeeded;
fileUpdateRequestDeferral.Complete();
}
}
else if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Remote) // 由 app 更新 CachedFile(CachedFileTarget.Remote 方式)
{
// CachedFileUpdater 返回給 app 一個 FileUpdateStatus 狀態
_fileUpdateRequest.Status = FileUpdateStatus.Complete;
fileUpdateRequestDeferral.Complete();
}
}
private async void btnUpdate_Click_1(object sender, RoutedEventArgs e)
{
FileUpdateRequestDeferral fileUpdateRequestDeferral = _fileUpdateRequest.GetDeferral();
// 由 CachedFileUpdater 更新 CachedFile,然後返回給 app 一個 FileUpdateStatus 狀態
await FileIO.AppendTextAsync(_fileUpdateRequest.File, Environment.NewLine + "由 CachedFileUpdater 更新:" + DateTime.Now.ToString());
string fileContent = await FileIO.ReadTextAsync(_fileUpdateRequest.File);
lblMsg.Text = "文件名: " + _fileUpdateRequest.File.Name;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "文件內容: " + fileContent;
_fileUpdateRequest.Status = FileUpdateStatus.Complete;
fileUpdateRequestDeferral.Complete();
btnUpdate.IsEnabled = false;
}
}
}
3、判斷程序是否是由文件打開選取器激活或者是否是由緩存文件更新程序激活
App.xaml.cs
// 通過文件打開選取器激活應用程序時所調用的方法
protected override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args)
{
var rootFrame = new Frame();
rootFrame.Navigate(typeof(MyOpenPicker), args);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
// 通過緩存文件更新程序(CachedFileUpdater)激活應用程序時所調用的方法
protected override void OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args)
{
var rootFrame = new Frame();
rootFrame.Navigate(typeof(MyCachedFileUpdater), args);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
二、在 app 中調用 CachedFileUpdater
1、演示如何調用 CachedFileUpdater(緩存文件更新 程序)
Picker/CachedFileUpdaterDemo.xaml
<Page
x:Class="XamlDemo.Picker.CachedFileUpdaterDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlDemo.Picker"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<StackPanel Margin="120 0 0 0">
<TextBlock Name="lblMsg" FontSize="14.667" />
<Button Name="btnGetCachedFile" Content="打開 Provider 提供的 CachedFile" Click="btnGetCachedFile_Click_1" Margin="0 10 0 0" />
<Button Name="btnReadCachedFile" Content="由 CachedFileUpdater 更新文件" Click="btnReadCachedFile_Click_1" Margin="0 10 0 0" />
<Button Name="btnWriteCachedFile" Content="由 app 更新文件" Click="btnWriteCachedFile_Click_1" Margin="0 10 0 0" />
</StackPanel>
</Grid>
</Page>
Picker/CachedFileUpdaterDemo.xaml.cs
/*
* 演示如何調用 CachedFileUpdater(緩存文件更新程序)
*
* 流程:
* 1、單擊“打開 Provider 提供的 CachedFile”按鈕,以彈出打開文件對話框
* 2、在彈出的對話框中選擇 CachedFileUpdaterProvider,以打開 CachedFileUpdaterProvider 項目中的 MyOpenPicker.xaml
* 3、在 provider 中單擊“提供一個 CachedFile”按鈕,以打開一個文件,同時將此文件關聯到 CachedFileUpdater
* 4、如果在 provider 選擇了“提供一個由 Local 更新的 CachedFile”則轉到(5);如果在 provider 選擇了“提供一個由 Remote 更新的 CachedFile”則轉到(6)
*
* 5、單擊“由 CachedFileUpdater 更新文件”按鈕,激活 CachedFileUpdater,獲取由 CachedFileUpdater 修改後的文件(CachedFileUpdater 的 Local 方式)
* 6、單擊“由 app 更新文件”按鈕,會在 app 端更指定的 CachedFile,需要的話可以激活 CachedFileUpdater 做一些別的處理(CachedFileUpdater 的 Remote 方式)
*
*
* 注:app 代表調用方,provider 代表緩存文件提供方,CachedFileUpdater 代表緩存文件更新程序
*/
using System;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlDemo.Picker
{
public sealed partial class CachedFileUpdaterDemo : Page
{
private string _cachedFileToken;
public CachedFileUpdaterDemo()
{
this.InitializeComponent();
}
private async void btnGetCachedFile_Click_1(object sender, RoutedEventArgs e)
{
if (XamlDemo.Common.Helper.EnsureUnsnapped())
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".txt");
// 彈出打開文件對話框後,選擇 CachedFileUpdaterProvider,以獲取 CachedFile
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
_cachedFileToken = StorageApplicationPermissions.FutureAccessList.Add(file);
string fileContent = await FileIO.ReadTextAsync(file);
lblMsg.Text = "文件名: " + file.Name;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "文件內容: " + fileContent;
}
else
{
lblMsg.Text = "取消了";
}
}
}
// 由 CachedFileUpdater 更新文件(CachedFileUpdater 的 Local 方式)
private async void btnReadCachedFile_Click_1(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(_cachedFileToken))
{
StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken);
string fileContent = await FileIO.ReadTextAsync(file);
lblMsg.Text = "文件名: " + file.Name;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "文件內容: " + fileContent;
}
}
// 由 app 更新文件(CachedFileUpdater 的 Remote 方式)
private async void btnWriteCachedFile_Click_1(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(_cachedFileToken))
{
StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken);
// 開始異步更新操作(不需要激活 CachedFileUpdater 的話可以不走這一步)
CachedFileManager.DeferUpdates(file);
// 更新文件
await FileIO.AppendTextAsync(file, Environment.NewLine + "由 app 更新:" + DateTime.Now.ToString());
// 通知系統已完成異步操作(之前激活的 CachedFileUpdater 會返回一個 FileUpdateStatus)
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
lblMsg.Text = status.ToString();
lblMsg.Text += Environment.NewLine;
if (status == FileUpdateStatus.Complete)
{
string fileContent = await FileIO.ReadTextAsync(file);
lblMsg.Text += "文件名: " + file.Name;
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "文件內容: " + fileContent;
}
}
}
}
}
OK
[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar