背水一戰 Windows 10 (97) - 選取器: CachedFileUpdater

[源碼下載]


html

背水一戰 Windows 10 (97) - 選取器: CachedFileUpdater



做者:webabcd


介紹
背水一戰 Windows 10 之 選取器html5

  • CachedFileUpdater(緩存文件更新程序)



示例
一、演示如何開發自定義緩存文件更新程序
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
[源碼下載]

相關文章
相關標籤/搜索