原文 理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图)

UWP 应用多是一个窗口完成所有业务的,事实上我也推荐使用这种单一窗口的方式。不过,总有一些特别的情况下我们需要用到不止一个窗口,那么 UWP 中如何使用多窗口呢?


为什么 UWP 需要多窗口?

多窗口在传统 Win32 的开发当中是司空见惯的事儿了,不过我个人非常不喜欢,因为 Windows 系统上的多窗口太多坑。以下是我以前写的关于传统多窗口开发中的一些坑(除此之外还有更多):

使用多窗口的原因很简单 —— 允许用户多任务处理。从这个角度来说,传统 Win32 使用“模态”多窗口的方式简直是低效的同时还带来 Bug!

微软官方文档中列举了一些例子:例如一边写邮件一边参考以往的邮件;一边看正在播放的音乐一边浏览播放列表;一次性打开多份文章然后稍后一起阅读等。

UWP 视图的概念

在学习如何编写 UWP 多窗口之前,我们需要了解一些 UWP 视图(View)的概念。

在 CoreApplication/Application、CoreWindow/Window 之间的区别 一文中,我描述了 UWP 视图的一些概念:

CoreApplication 管理一个 UWP 应用中的所有视图(View),而 CoreApplication直接管理的视图是 CoreApplicationView;也就是说,UWP 应用 CoreApplication管理所有的应用视图 CoreApplicationView。而一个 CoreApplicationView 包含一个窗口和一个线程调度模型,即 CoreWindow 和 CoreDispatcher

CoreWindow 就是我们所理解的窗口。为了方便使用,Windows.UI.XAML.Window 类型封装了这个 CoreWindowCoreDispatcher 是基于消息循环的线程调度模型,正是因为有了消息循环,所以此窗口才能一直显示而不被销毁。

在 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序 一文中,我们也能体会到 CoreApplication 和 CoreWindow 之间的关系,了解消息循环在应用中的作用。

UWP 多窗口

在了解到 UWP 视图的概念之后,严格意义上说,这一节的标题应该叫做 “UWP 多视图”。

我画了一个思维导图来描述它们之间的关系。CoreApplication 有静态方法 CreateNewView,调用后能够创建新的 CoreApplicationView,这包含一个完整的 CoreWindow 和 CoreDispatcher

创建并显示一个新 CoreApplicationView 的代码如下:

private async void OnLoaded(object sender, RoutedEventArgs e)
{
// 创建一个 CoreApplicationView,即新的应用视图。
var applicationView = CoreApplication.CreateNewView(); // 一个应用视图有自己的 Id,稍后我们创建应用视图的时候,需要记录这个 Id。
int newViewId = 0; // 使用新应用视图的 CoreDispatcher 线程调度模型来执行新视图中的操作。
await applicationView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// 在新的应用视图中,我们将新的窗口内容设置为 ThePageInNewView 页面。
Frame frame = new Frame();
frame.Navigate(typeof(ThePageInNewView), null);
Window.Current.Content = frame;
Window.Current.Activate(); // 记录新应用视图的 Id,这样才能稍后切换。
newViewId = ApplicationView.GetForCurrentView().Id;
}); // 使用刚刚记录的新应用视图 Id 显示新的应用视图。
var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}

创建完后的效果如下图:

管理多个 UWP 视图

我们平时开发 UWP 应用的时候很少去关心 CoreApplicationView,因为默认情况下 UWP 能为我们做很多管理应用视图的工作。

CoreApplication 有一个 MainView 属性,即我们一开始运行 UWP 应用时的那个应用视图。如果我们有不止一个应用视图显示出来,那么这时点击主窗口的关闭按钮将不再是关闭,而是隐藏。如果要关闭,需要调用 Application.Exit

CoreApplication 有 Views 属性储存所有的 CoreApplicationView,我们可以使用此集合来管理多个视图。使用 ApplicationViewSwitcher.SwitchAsync 并传入视图 Id 可以切换视图的显示。

await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);

参考资料

本文会经常更新,请阅读原文: https://walterlv.com/post/show-multiple-views-for-an-uwp-app.html,以避免陈旧错误知识的误导,同时有更好的阅读体验。

理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图)的更多相关文章

  1. Effective Objective-C 2.0 — 第二章 对象、消息、运行期 - 第六条:理解“属性”这一概念

    开发者通过对象来 存储并传递数据. 在对象之间传递数据并执行任务的过程就叫做“消息传递”. 这两条特性的工作原理? Objective-C运行期环境(Objective-C runtime) ,提供了 ...

  2. 理解maven的核心概念

    原文出处:http://www.cnblogs.com/holbrook/archive/2012/12/24/2830519.html 好久没进行java方面的开发了,最近又完成了一个java相关的 ...

  3. MySql中的视图的概念及应用

    视图的基本概念 视图是从一个或几个基本表(或者视图)导出的表.它与基本表不同,是一个虚表. 数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中.所以基本表中的数据发生变化, ...

  4. 物化视图基础概念、mview跨库迁移表

    概念:物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询.这样 ...

  5. uwp - 上滑隐藏导航栏下滑显示

    原文:uwp - 上滑隐藏导航栏下滑显示 好久没写博客了,因为忙着工作.昨天周末填坑需要做一个上滑列表数据时隐藏导航栏下滑时显示的效果,下面分享一下我的做法,希望能给你带来帮助. 思路是通过判断滚动条 ...

  6. iOS开发之窗口和视图

    视图就是应用程序的界面.视图可以使用nib文件实现,也可以使用代码创建.一个视图也是一个响应器(UIResponder的子类)这意味着一个视图可以与用户交互.因此,视图不只是用户可看到的界面,也是可以 ...

  7. [UWP] 用 AudioGraph 来增强 UWP 的音频处理能力

    Audio Graph AudioGraph 是 Windows.Media.Audio 命名空间下提供的音频处理接口之一. 可以通过 AudioGraph 的静态方法 CreateAsync 来实例 ...

  8. 理解screenX clientX pageX概念

    先了解screenX,clientX,pageX概念 screenX: 鼠标位置相对于用户屏幕水平偏移量,而screenY就是垂直方向的,此时的参照点也就是原点是屏幕的左上角. clientX: 跟s ...

  9. 理解MySQL——架构与概念

    写在前面:最早接触的MySQL是在三年前,那时候MySQL还是4.x版本,很多功能都不支持,比如,存储过程,视图,触发器,更别说分布式事务等复杂特性了.但从5.0(2005年10月)开始,MySQL渐 ...

随机推荐

  1. BI并不是万能,中层业务管理报表要另辟蹊径

           BI是商业智能的缩写,是能够帮助企业做出明智的业务经营决策的工具.其数据来源于各个业务系统.如ERP.CRM.SCM.进销存.HER.OA等.        BI系统不同于传统的管理信息 ...

  2. arm-linux-gcc: Command not found

    老是提示arm-linux-gcc找不到,但是确实是装好了,其实是权限的问题,Ubuntu没有root权限,刚开始用碰到很多麻烦,查了好多资料,终于把arm-linux-gcc: Command no ...

  3. P2P网贷第三方托管模式存在5大缺陷,托管机构才是最大赢家

    1.注册开户需要2次,用户体验很差劲儿.   理财人和借款人,首先在平台注册,然后还要在第三方托管账户注册.   很多类似的地方,用户体验非常差劲.   比如,密码4个.   平台:登录密码.交易密码 ...

  4. WIFI 状态栏显示的wifi信号强度与wifisetting列表不一致

    [DESCRIPTION] 状态栏显示的wifi信号强度与wifisetting列表不一致(不同步) [ANALYSIS] 1.apk都是接收RSSI_CHANGED intent,并调用WifiMa ...

  5. 【Android开源框架】使用andbase开发框架实现绘制折线图

    在Android中,当有绘制折线图的需求时.大多数人使用的AChartEngine,来进行折线图的绘制.AChartEngine图表引擎确实能够实现折线图的功能.除此之外,我们还能够使用andbase ...

  6. 《编程导论(Java)·4.1数据抽象的含义》

    You have no choice about the necessity to integrateyour observations, your experiences, your knowled ...

  7. 【2013】将x插入有序数列

    Time Limit: 3 second Memory Limit: 2 MB 将一个数x插入到有序数列a中,插入后a仍然有序. Input 第一行输入有序数列a的元素个数 第二行依次输入a的元素,以 ...

  8. Android Widget和悬浮窗 原理

    1.简单介绍 Android widget是桌面插件,在android系统应用开发层面有特殊用途. AppWidget是把一个进程的控件嵌入到别外一个进程的窗口里的一种方法.悬浮窗的效果与Widget ...

  9. js进阶js中支持正则的四个常用字符串函数(search march replace split)

    js进阶js中支持正则的四个常用字符串函数(search march replace split) 一.总结 代码中详细四个函数的用法 search march replace split 二.js进 ...

  10. [RxJS] Split an RxJS Observable into groups with groupBy

    groupBy() is another RxJS operator to create higher order observables. In this lesson we will learn ...