zoukankan      html  css  js  c++  java
  • UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面【UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理】章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例。

    原代码地址:https://github.com/NewBLife/UWP/tree/master/MvvmDemo/FileOperationDemo

    应用主要功能:

    1. 本地任何文件多项选择添加
    2. 照相机图片添加
    3. 显示添加文件(.jpg.png.pdf.xls等)的缩略图
    4. 列表文件删除
    5. 默认程序显示添加后的文件

    应用技术点:

    1. 汉堡菜单(随窗口大小自动收缩)
    2. 系统返回按钮操作
    3. StorageFile挂起复原
    4. 文件访问权限

    应用截图如下:

    ====PC端====

    主界面

    image

    点击【+】添加文件

    image

    点击列表任何文件(例如:0.PNG),使用默认应用打开文件

    image

    点击【头像】拍照

    imageimage

    image

    点击【Delete】可以删除列表文件

    点击【设定】打开设定页面

    image

    ====手机端====

    主界面

    image

    点击【+】添加文件

    image

    选择任何文件(例如:list.pdf),使用默认应用打开文件

    image

    点击【头像】拍照

    image

    image

    点击汉堡菜单选择【设定】

    image

    技术详解:

    1.StorageFile文件的挂起复原

    应用以外文件夹的文件挂起复原时如果通过路径获取StorageFile对象会出现以下异常,一般是通过令牌来做处理。

    “System.UnauthorizedAccessException”类型的异常在 FileOperationDemo.exe 中发生,但未在用户代码中进行处理
    
    其他信息: 拒绝访问。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
    第一步:添加时从MRU中获取文件访问令牌
    #region 获取 MRU 中文件的令牌
                // 详细: https://msdn.microsoft.com/zh-cn/library/windows/apps/hh972603
                // 应用外部文件访问时使用
                _FileMruToken = StorageApplicationPermissions.FutureAccessList.Add(file);
                #endregion

    第二步:应用挂起时只保存令牌数据StorageFile属性JsonIgnore标记添加(StorageFile等对象无法反序列化复原)

    /// <summary>
            /// 文件信息
            /// </summary>
            [JsonIgnore]
            public StorageFile File
            {
                get
                {
                    return _File;
                }
    
                set
                {
                    Set(ref _File, value);
                }
            }
            /// <summary>
            /// 文件访问令牌
            /// 挂起复原时使用
            /// </summary>
            [JsonProperty]
            public string FileMruToken
            {
                get
                {
                    return _FileMruToken;
                }
    
                set
                {
                    _FileMruToken = value;
                }
            }

    第三步:复原时使用令牌获取StorageFile对象

    // 应用外部文件
                    return await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_FileMruToken);

    2.默认应用打开文件时权限取得

    // 默认应用打开文件
                            await Windows.System.Launcher.LaunchFileAsync(file);

    直接赋值StorageFile对象到file时,是无法打开文件的,因为没有权限。这时也需要令牌从StorageApplicationPermissions.FutureAccessList获取StorageFile对象才能打开。

    // 应用外部文件 
    return await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_FileMruToken);

    3.系统返回按钮事件注销时机

    由于不想应用最后返回按下时关闭特加入此功能

    /// <summary>
            /// 返回按钮事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnBackRequested(object sender, BackRequestedEventArgs e)
            {
                e.Handled = true;
                NavigationService.GoBack();
            }

    在OnNavigatedToAsync注册事件

    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
            {
                try
                {
                    if (suspensionState.Any())
                    {
                        FileList = SerializationService.Json.Deserialize<ObservableCollection<FileInfo>>(suspensionState[nameof(FileList)]?.ToString());
                    }
    
                    // 注册系统返回按钮事件
                    SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
                    await Task.CompletedTask;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Debug.WriteLine(ex.Source);
                    Debug.WriteLine(ex.StackTrace);
                }
            }
    在OnNavigatingFromAsync注销事件
    public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
            {
                args.Cancel = false;
                // 注销系统返回按钮事件
                SystemNavigationManager.GetForCurrentView().BackRequested -= OnBackRequested;
                await Task.CompletedTask;
            }
  • 相关阅读:
    css基础面试题
    hack-checkbox
    装饰性属性
    【CF809E】Surprise me!
    [SCOI2012]奇怪的游戏
    [HAOI2018]奇怪的背包
    CF1139D Steps to One
    [CTSC2018]假面
    写在省选前
    [SDOI2015]寻宝游戏
  • 原文地址:https://www.cnblogs.com/lixiaobin/p/Template10Mvvm.html
Copyright © 2011-2022 走看看