• 背水一战 Windows 10 (97)


    [源码下载]


    背水一战 Windows 10 (97) - 选取器: CachedFileUpdater



    作者:webabcd


    介绍
    背水一战 Windows 10 之 选取器

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



    示例
    1、演示如何开发自定义缓存文件更新程序
    CachedFileUpdaterProvider/App.xaml.cs

            // 通过缓存文件更新程序(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.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="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.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;
    
                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;
            }
        }
    }


    2、打开一个文件,并关联到 CachedFileUpdater
    CachedFileUpdaterProvider/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();
            }

    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.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)
            {
                // 获取 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);
            }
        }
    }


    3、演示如何调用 CachedFileUpdater(缓存文件更新程序)
    Picker/CachedFileUpdaterDemo.xaml

    <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(缓存文件更新程序)
     * 
     * 流程:
     * 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 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
    [源码下载]

  • 相关阅读:
    idea中pom.xml相关操作
    Java集合1-集合与数组的区别
    idea中各种图标的含义
    testng之多线程执行(并发执行)
    testng之DataProvider参数化
    fastjson将java对象与json字符串相互转换
    testng -依赖测试
    testng- 异常测试
    转-selenium3 webdriver启动火狐、chrome、edge、Safari浏览器的方法
    浏览器兼容性测试
  • 原文地址:https://www.cnblogs.com/webabcd/p/9185846.html
Copyright © 2020-2023  润新知