posts - 615, comments - 10473, trackbacks - 594, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

公告

背水一战 Windows 10 (95) - 选取器: 自定义文件保存选取器

Posted on 2018-06-15 08:26 webabcd 阅读(...) 评论(...) 编辑 收藏

[源码下载]


背水一战 Windows 10 (95) - 选取器: 自定义文件保存选取器



作者:webabcd


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

  • 自定义文件保存选取器



示例
1、演示如何开发自定义文件保存选取器
App.xaml.cs

        // 通过文件保存选取器激活应用程序时所调用的方法
        protected override void OnFileSavePickerActivated(FileSavePickerActivatedEventArgs args)
        {
            var rootFrame = new Frame();
            rootFrame.Navigate(typeof(Windows10.Picker.MySavePicker), args);
            Window.Current.Content = rootFrame;

            Window.Current.Activate();
        }

Picker/MySavePicker.xaml

<Page
    x:Class="Windows10.Picker.MySavePicker"
    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" />

        </StackPanel>
    </Grid>
</Page>

Picker/MySavePicker.xaml.cs

/*
 * 演示如何开发自定义文件保存选取器
 * 
 * 1、在 Package.appxmanifest 中新增一个“文件保存选取器”声明,并做相关配置
 * 2、在 App.xaml.cs 中 override void OnFileSavePickerActivated(FileSavePickerActivatedEventArgs args),如果 app 是由文件保存选取器激活的,则会调用此方法
 * 
 * FileSavePickerActivatedEventArgs - 通过“文件保存选取器”激活应用程序时的事件参数
 *     FileSavePickerUI - 获取 FileSavePickerUI 对象
 *     Kind - 此 app 被激活的类型(ActivationKind 枚举)
 *         比如,如果是通过“文件打开选取器”激活的话,则此值为 FileOpenPicker
 *     PreviousExecutionState - 此 app 被激活前的状态(ApplicationExecutionState 枚举)
 *         比如,如果此 app 被激活前就是运行状态的或,则此值为 Running
 *     SplashScreen - 获取此 app 的 SplashScreen 对象
 *     CallerPackageFamilyName - 获取激活了此 app 的应用的包名(但是实际测试发现,获取到的却是此 app 的包名)
 *     User - 获取激活了此 app 的 User 对象
 *     
 * FileSavePickerUI - 自定义文件保存选取器的帮助类
 *     AllowedFileTypes - 允许的文件类型,只读
 *     Title - 将在“自定义文件保存选取器”上显示的标题
 *     FileName - 需要保存的文件名(包括文件名和扩展名),只读
 *     TrySetFileName(string value) - 尝试指定需要保存的文件名(包括文件名和扩展名)
 *     FileNameChanged - 用户在文件名文本框中更改文件名或在文件类型下拉框中更改扩展名时触发的事件
 *     TargetFileRequested - 用户提交保存时触发的事件(事件参数:TargetFileRequestedEventArgs)
 *     
 * TargetFileRequestedEventArgs
 *     Request - 返回 TargetFileRequest 对象
 *     
 * TargetFileRequest
 *     TargetFile - 目标文件对象,用于返回给 client
 *     GetDeferral() - 获取异步操作对象,同时开始异步操作,之后通过 Complete() 通知完成异步操作
 */

using System;
using System.Collections.Generic;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Pickers.Provider;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Windows10.Picker
{
    public sealed partial class MySavePicker : Page
    {
        private FileSavePickerUI _fileSavePickerUI;

        public MySavePicker()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // 获取 FileSavePickerUI 对象(从 App.xaml.cs 传来的)
            FileSavePickerActivatedEventArgs args = (FileSavePickerActivatedEventArgs)e.Parameter;
            _fileSavePickerUI = args.FileSavePickerUI;

            _fileSavePickerUI.Title = "自定义文件保存选取器";

            // 通过 AllowedFileTypes 获取到的允许的扩展名是在调用端的 FileSavePicker.FileTypeChoices 中配置的,实际保存扩展名可以不与其匹配
            IReadOnlyList<string> allowedFileTypes = _fileSavePickerUI.AllowedFileTypes;
            lblMsg.Text = "allowedFileTypes: " + string.Join(",", allowedFileTypes);
            lblMsg.Text += Environment.NewLine;

            lblMsg.Text += "Kind: " + args.Kind;
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "SplashScreen.ImageLocation: " + args.SplashScreen.ImageLocation;
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "PreviousExecutionState: " + args.PreviousExecutionState;
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "CallerPackageFamilyName: " + args.CallerPackageFamilyName;
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "User.NonRoamableId: " + args.User.NonRoamableId;
            lblMsg.Text += Environment.NewLine;

            _fileSavePickerUI.TargetFileRequested += _fileSavePickerUI_TargetFileRequested;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            _fileSavePickerUI.TargetFileRequested -= _fileSavePickerUI_TargetFileRequested;
        }

        private async void _fileSavePickerUI_TargetFileRequested(FileSavePickerUI sender, TargetFileRequestedEventArgs args)
        {
            // 异步操作
            var deferral = args.Request.GetDeferral();

            try
            {
                // 在指定的地址新建一个没有任何内容的空白文件
                StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sender.FileName, CreationCollisionOption.GenerateUniqueName);

                // 设置 TargetFile,“自定义文件保存选取器”的调用端会收到此对象
                args.Request.TargetFile = file;
            }
            catch (Exception ex)
            {
                // 输出异常信息
                OutputMessage(ex.ToString());
            }
            finally
            {
                // 完成异步操作
                deferral.Complete();
            }
        }

        private async void OutputMessage(string msg)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                lblMsg.Text = msg;
            });
        }
    }
}


2、演示如何调用自定义文件保存选取器
Picker/MySavePickerDemo.xaml

<Page
    x:Class="Windows10.Picker.MySavePickerDemo"
    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">
                <Run>
                    如果需要激活自定义的文件保存窗口,请在弹出的选取器窗口的左侧的导航列表中选择相应的 app
                </Run>
            </TextBlock>

            <Button Name="btnMySavePicker" Content="弹出文件保存窗口" Click="btnMySavePicker_Click" Margin="5" />

        </StackPanel>
    </Grid>
</Page>

Picker/MySavePickerDemo.xaml.cs

/*
 * 演示如何调用自定义文件保存选取器
 * 
 * 自定义文件保存选取器参见 MySavePicker.xaml
 */

using System;
using System.Collections.Generic;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using Windows.UI.Xaml.Controls;

namespace Windows10.Picker
{
    public sealed partial class MySavePickerDemo : Page
    {
        public MySavePickerDemo()
        {
            this.InitializeComponent();
        }

        private async void btnMySavePicker_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            FileSavePicker savePicker = new FileSavePicker();
            savePicker.FileTypeChoices.Add("文本", new List<string>() { ".txt" });

            // 弹出文件保存窗口
            StorageFile file = await savePicker.PickSaveFileAsync();
            if (file != null)
            {
                /*
                 * 运行到此,只是在目标地址创建了一个没有任何内容的空白文件而已,接下来开始向文件写入内容
                 */

                // 告诉 Windows ,从此时开始要防止其它程序更新指定的文件
                CachedFileManager.DeferUpdates(file);

                // 将指定的内容保存到指定的文件
                string textContent = "I am webabcd";
                await FileIO.WriteTextAsync(file, textContent);

                // 告诉 Windows ,从此时开始允许其它程序更新指定的文件
                FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
                if (status == FileUpdateStatus.Complete)
                {
                    lblMsg.Text = "文件 " + file.Name + " 保存成功";
                }

                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "FileUpdateStatus: " + status.ToString();
            }
            else
            {
                lblMsg.Text = "取消了";
            }
        }
    }
}



OK
[源码下载]