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;
        }
原文地址:https://www.cnblogs.com/lixiaobin/p/Template10Mvvm.html