[源碼下載]
html
做者:webabcd
介紹
背水一戰 Windows 10 之 選取器html5
示例
一、演示如何開發自定義緩存文件更新程序
CachedFileUpdaterProvider/App.xaml.csc++
// 經過緩存文件更新程序(CachedFileUpdater)激活應用程序時所調用的方法 protected override void OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args) { var rootFrame = new Frame(); rootFrame.Navigate(typeof(MyCachedFileUpdater), args); Window.Current.Content = rootFrame; Window.Current.Activate(); }
CachedFileUpdaterProvider/MyCachedFileUpdater.xamlweb
<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="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="btnUpdate" Content="更新 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnUpdate_Click" Margin="5" /> </StackPanel> </Grid> </Page>
CachedFileUpdaterProvider/MyCachedFileUpdater.xaml.csexpress
/* * 演示如何開發自定義緩存文件更新程序 * * 一、在 Package.appxmanifest 中新增一個「緩存文件更新程序」聲明,並作相關配置 * 二、在 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; base.OnNavigatedTo(e); } // 須要顯示 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(); }); } async void _cachedFileUpdaterUI_FileUpdateRequested(CachedFileUpdaterUI sender, FileUpdateRequestedEventArgs args) { _fileUpdateRequest = args.Request; FileUpdateRequestDeferral fileUpdateRequestDeferral = _fileUpdateRequest.GetDeferral(); if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Local) // 由 CachedFileUpdater 更新 CachedFile(CachedFileTarget.Local 方式) { // 開始激活 CachedFileUpdater 時,是 UIStatus.Hidden 狀態的 if (_cachedFileUpdaterUI.UIStatus == UIStatus.Hidden) { // 下面針對兩種方式分別寫示例 // 方式一:直接更新文件,並設置爲 FileUpdateStatus.Complete 狀態,最後完成 if (DateTime.Now.Second % 2 == 0) { await FileIO.AppendTextAsync(_fileUpdateRequest.File, Environment.NewLine + "由 CachedFileUpdater 更新:" + DateTime.Now.ToString()); _fileUpdateRequest.Status = FileUpdateStatus.Complete; fileUpdateRequestDeferral.Complete(); } // 方式二:設置爲 FileUpdateStatus.UserInputNeeded 狀態,並完成,以後會再次觸發這個事件,而且變爲 UIStatus.Visible 狀態,彈出本頁界面, // 這樣的話能夠在用戶作一些操做以後再更新文件(參見下面的 btnUpdate_Click 部分) else { _fileUpdateRequest.Status = FileUpdateStatus.UserInputNeeded; fileUpdateRequestDeferral.Complete(); } } } else if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Remote) // 由 app 更新 CachedFile(CachedFileTarget.Remote 方式) { // 這裏能夠拿到 app 更新後的文件的結果 string textContent = await FileIO.ReadTextAsync(_fileUpdateRequest.File); // 可是這裏不能修改這個文件,不然會報錯 // await FileIO.AppendTextAsync(_fileUpdateRequest.File, Environment.NewLine + "由 CachedFileUpdater 更新:" + DateTime.Now.ToString()); // CachedFileUpdater 返回給 app 一個 FileUpdateStatus 狀態 _fileUpdateRequest.Status = FileUpdateStatus.Complete; fileUpdateRequestDeferral.Complete(); } } private async void btnUpdate_Click(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; } } }
二、打開一個文件,並關聯到 CachedFileUpdater
CachedFileUpdaterProvider/App.xaml.cswindows
// 經過文件打開選取器激活應用程序時所調用的方法 protected override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args) { var rootFrame = new Frame(); rootFrame.Navigate(typeof(MyOpenPicker), args); Window.Current.Content = rootFrame; Window.Current.Activate(); }
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="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="btnPickCachedFileLocal" Content="提供一個由 Local 更新的 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnPickCachedFileLocal_Click" Margin="5" /> <Button Name="btnPickCachedFileRemote" Content="提供一個由 Remote 更新的 CachedFile(由 app 更新 CachedFile)" Click="btnPickCachedFileRemote_Click" Margin="5" /> </StackPanel> </Grid> </Page>
CachedFileUpdaterProvider/MyOpenPicker.xaml.csapp
/* * 打開一個文件,並關聯到 CachedFileUpdater * * 一、在 Package.appxmanifest 中新增一個「文件打開選取器」聲明,並作相關配置 * 二、在 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) { // 獲取 FileOpenPickerUI 對象(從 App.xaml.cs 傳來的) var args = (FileOpenPickerActivatedEventArgs)e.Parameter; _fileOpenPickerUI = args.FileOpenPickerUI; _fileOpenPickerUI.Title = "自定義文件打開選取器"; base.OnNavigatedTo(e); } // 本 CachedFile 用於從 Local 更新(由 CachedFileUpdater 更新 CachedFile) private async void btnPickCachedFileLocal_Click(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 更新(由 app 更新 CachedFile) private async void btnPickCachedFileRemote_Click(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); } } }
三、演示如何調用 CachedFileUpdater(緩存文件更新程序)
Picker/CachedFileUpdaterDemo.xamlasp.net
<Page x:Class="Windows10.Picker.CachedFileUpdaterDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.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="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="btnGetCachedFile" Content="打開 Provider 提供的 CachedFile" Click="btnGetCachedFile_Click" Margin="5" /> <Button Name="btnReadCachedFile" Content="由 CachedFileUpdater 更新文件" Click="btnReadCachedFile_Click" Margin="5" /> <Button Name="btnWriteCachedFile" Content="由 app 更新文件" Click="btnWriteCachedFile_Click" Margin="5" /> </StackPanel> </Grid> </Page>
Picker/CachedFileUpdaterDemo.xaml.cs異步
/* * 演示如何調用 CachedFileUpdater(緩存文件更新程序) * * 流程: * 一、單擊「打開 Provider 提供的 CachedFile」按鈕,以彈出打開文件對話框 * 二、在彈出的對話框中選擇 CachedFileUpdaterProvider,以打開 CachedFileUpdaterProvider 項目中的 MyOpenPicker.xaml * 三、在 provider 中單擊「提供一個 CachedFile」按鈕,以打開一個文件,同時將此文件關聯到 CachedFileUpdater * 四、若是在 provider 選擇了「提供一個由 Local 更新的 CachedFile」則轉到(5);若是在 provider 選擇了「提供一個由 Remote 更新的 CachedFile」則轉到(6) * * 五、單擊「由 CachedFileUpdater 更新文件」按鈕,激活 CachedFileUpdater,獲取由 CachedFileUpdater 修改後的文件(CachedFileUpdater 的 Local 方式) * 六、單擊「由 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 Windows10.Picker { public sealed partial class CachedFileUpdaterDemo : Page { private string _cachedFileToken; public CachedFileUpdaterDemo() { this.InitializeComponent(); } private async void btnGetCachedFile_Click(object sender, RoutedEventArgs e) { 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(object sender, RoutedEventArgs e) { if (!string.IsNullOrEmpty(_cachedFileToken)) { try { StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken); // 獲取的文件是 CachedFile,且是 CachedFileUpdater 的 Local 方式 // 如此就會激活 CachedFileUpdater,由 CachedFileUpdater 更新文件並返回 string fileContent = await FileIO.ReadTextAsync(file); lblMsg.Text = "文件名: " + file.Name; lblMsg.Text += Environment.NewLine; lblMsg.Text += "文件內容: " + fileContent; } catch (Exception ex) { lblMsg.Text = ex.ToString(); } } } // 由 app 更新文件(CachedFileUpdater 的 Remote 方式) private async void btnWriteCachedFile_Click(object sender, RoutedEventArgs e) { if (!string.IsNullOrEmpty(_cachedFileToken)) { try { StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken); // 開始異步更新操做(不須要激活 CachedFileUpdater 的話能夠不走這一步) CachedFileManager.DeferUpdates(file); // 更新文件 await FileIO.AppendTextAsync(file, Environment.NewLine + "由 app 更新:" + DateTime.Now.ToString()); // 通知系統已完成異步操做(以前激活的 CachedFileUpdater 會返回一個 FileUpdateStatus) // 更新的文件是 CachedFile,且是 CachedFileUpdater 的 Remote 方式,即 app 更新 // 更新後會激活 CachedFileUpdater,在 CachedFileUpdater 中能夠拿到更新後的文件 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; } } catch (Exception ex) { lblMsg.Text = ex.ToString(); } } } } }
OK
[源碼下載]