Windows App一般情况下,同一时刻只能有一个应用程序实例在运行,为了在特殊需求下可以同时呈现不同的UI,SDK提供了多视图操作支持。

应用程序可以创建新的应用视图,以新的视图为基础可以呈现与主视图不同的内容,但又不影响主视图的UI。这些视图既可以在同一个窗口中切换,也可以用新的窗口来呈现新的视图。这些窗口,用户可以拖放到不同的虚拟桌面中。

其实,视图的创建、切换、显示都不难,主要的难点在于完成这些操作所需要的类型被分布在不同的命名空间中,故不熟悉SDK的朋友可能找不到。

视图管理相关的API主要分布在以下两个命名空间下:

Windows.ApplicationModel.Core
 Windows.UI.ViewManagement

Core下面主要用到两个类。CoreApplication类负责创建视图,调用CreateNewView方法可以创建一个新的视图,创建后以CoreApplicationView对象返回。已创建的视图在CoreApplication.Views列表中,在应用程序运行期间,所有被创建的视图都在这个列表中,所以,还是节约一下资源,不要乱创建视图。

另外,在Windows.UI.ViewManagement命名空间下,也有几个类,也是用来操作视图,比较重要,上面的几个Core是用于创建视图,而ViewManagement下的类都是用来操作具体的某一个视图的。

ApplicationView类用于获取视图ID,设置视图标题等,其中,依靠ApplicationViewTitleBar类还可以自定窗口标题栏、标题栏按钮的背景颜色和前景颜色。

要在新窗口上显示某个视图,或者切换视图,都由ApplicationViewSwitcher类来完成,它是静态的,直接可以拿来耍,不用实例化。

下面我做了个例子,这个例子在主视图上放了几个网站链接,点击某个链接后,可以在新窗口中打开浏览目标网页。

核心代码如下:

            // 创建新的视图
CoreApplicationView newView = null;
if (CoreApplication.Views.Count > )
{
newView = CoreApplication.Views[];
}
// 如果没有这个视图,就创一个
if (newView == null)
{
newView = CoreApplication.CreateNewView();
} int newViewID = default(int); // 初始化视图
// 注意,必须在对应的线程上执行
await newView.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
// 获取视图ID,有两种方法
// 方法一:GetApplicationViewIdForWindow法,注意线程要对应
// Window必须是与当前视图关联的窗口
// int viewID = ApplicationView.GetApplicationViewIdForWindow(newView.CoreWindow);
// 方法二:最简单
// 因为当前执行的代码就在新视图的UI线程上的
// 所以GetForCurrentView所返回的就是刚创建的新视图
ApplicationView theView = ApplicationView.GetForCurrentView();
// 设置一下新窗口的标题(可选)
theView.Title = content;
// 必须记下视图ID
newViewID = theView.Id;
// 初始化视图的UI
ucDisplayPage uc = Window.Current.Content as ucDisplayPage;
if (uc == null)
{
uc = new ucDisplayPage();
uc.HorizontalAlignment = HorizontalAlignment.Stretch;
uc.VerticalAlignment = VerticalAlignment.Stretch;
uc.MinWidth = 450d;
uc.MinHeight = 300d;
Window.Current.Content = uc;
}
uc.TargetWebpageUri = uri;
Window.Current.Activate();
// 必须调用Activate方法,否则视图不能显示
/*
注意:
在App类中,Window.Current获取的是主视图(程序刚启动时,至少要有一个视图,不然用户连毛都看不见了)所在的窗口。
而因为此处的代码是在新创建的视图的UI线程上执行的,故Window.Current自然获取的是新视图所在的窗口。
*/
});
// 开始显示新视图
bool b = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewID); if (b)
{
// 成功显示新视图
}
else
{
// 视图显示失败
}

这里面其实没什么难点,关键点是你要理解。 CoreApplication.CreateNewView创建视图这个应该不难理解,但是在初始化新视图的UI时,一定一定一定要700%注意,每个视图都会由一个独立的UI线程来管理。所以,你的代码是在主视图里面写的,你不能直接在主视图中访问新视图,必须要从与新视图(CoreApplicationView对象)关联的Dispatcher来执行。

在插入到Dispatcher队列的代码中,Window.Current所指的已经不是主视图的窗口了,在App类中访问Window.Current当然返回的是主窗口,但是由于视图分布在不同的UI线程上,在新视图的Dispatcher中执行的代码,Window.Current得到的是新窗口的引用。

这时候可以和平时一样,给窗口的Content属性设置UI对象,安排新窗口要显示的内容。我的例子中用的是一个用户控件(User Control),这个不用我多介绍,凡是搞过Win开发的,不管你是WPF也好,WinForms也罢,肯定知道用户控件,就是用现有的控件进行二次组装,比重新开发一个控件方便。

由于使用ApplicationViewSwitcher来显示或切换视图时用的是视图ID(整数,很多时候是个负值,如-3122),因此我们必须获取新视图的ID号,才能用ApplicationViewSwitcher类来显示它。

一种方法是在Dispatcher插入的代码中访问ApplicationView.GetApplicationViewIdForWindow方法,它可以从新视图所属的窗口中获取到视图ID。

另一种最简单的方法是直接用ApplicationView.GetForCurrentView方法得到当前视图的引用,因为这行代码是写在新视图的UI线程上的,所以它获取到的自然是新视图的引用。GetForCurrentView方法在哪个线程上调用,它就获取那个线程关联的视图

最后一个关键点是,在新视图的线程上安排好窗口要显示的内容后,一定要调用窗口的Activate方法,保证窗口被激活,否则窗口会永远停留在初始屏幕。

在Win 8.1的时候,你不调用Activate方法也无所谓,因为8x的应用是全屏的,而10x的应用是既可以全屏,也可以窗口化的,所以,你一定要调用Activate方法。原理和做法与初始化App的OnLaunch方法中一样。

好了,关键点给大家分析了一下,重点是大家自己能不能理解,编程这玩意儿就是这样,理解了就轻松,不理解就脑痛。

下面来运行一下,点击主窗口上的链接,可以在新窗口中打开网页。而且你可以把新窗口拖到其他虚拟桌面上。

示例源代码下载:http://files.cnblogs.com/files/tcjiaan/MultiViewApp.zip

【Win 10应用开发】多窗口视图的更多相关文章

  1. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  2. 【Win 10 应用开发】导入.pfx证书

    这个功能其实并不常用,一般开发较少涉及到证书,不过,简单了解一下还是有必要的. 先来说说制作测试证书的方法,这里老周讲两种方法,可以生成用于测试的.pfx文件. 产生证书,大家都知道有个makecer ...

  3. 【Win 10应用开发】Adaptive磁贴模板的XML文档结构

    在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴的新XML模板. 同样道理,你依旧可以使用8.1时候的磁贴模板,在win ...

  4. 【Win 10应用开发】认识一下UAP项目

    Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...

  5. 【Win 10 应用开发】RTM版的UAP项目解剖

    Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...

  6. 【Win 10 应用开发】在代码中加载文本资源

    记得前一次,老周给大伙,不,小伙伴们介绍了如何填写 .resw 文件,并且在 XAML 中使用 x:Uid 标记来加载.也顺便给大伙儿分析了运行时是如何解析 .resw 文件的. 本来说好了,后续老周 ...

  7. 【Win 10应用开发】延迟共享

    延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...

  8. 【Win 10 应用开发】Toast通知激活应用——前台&后台

    老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...

  9. 【Win 10 应用开发】UI Composition 札记(一):视图框架的实现

    在开始今天的内容之前,老周先说一个问题,这个问题记得以前有人提过的. 设置 Windows.ApplicationModel.Core.CoreApplicationView.TitleBar.Ext ...

随机推荐

  1. javaweb学习记录(1)

    Java基础学习笔录 1.运行java程序,出现bad version number in.class file 编译器()的版本号高于运行环境(jre)的版本号,可以降低编译器版本号,也可以通过提升 ...

  2. linux下 SVN切换仓库地址命令

    svn switch --relocate (Old Repository Root) (New Repository Root)

  3. UML类图关系--继承(泛化)、实现、关联、聚合、组合、依赖

    在UML类图中,常见的有以下几种关系:  泛化(Generalization),  实现(Realization),关联(Association),聚合(Aggregation),组合(Composi ...

  4. 安卓图标IconFont使用

    一.补充知识:PNG.IconFont.SVG理论 PNG为位图,是由不同的排列和染色的像素点组成的图像,位图的扩大实质是增加单个像素点的大小,故而导致在不同分辨率表现非常糟糕. SVG为可缩放矢量图 ...

  5. Struct2 csv文件上传读取中文内容乱码

    网络上搜索下,发现都不适合 最终改写代码: FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br= n ...

  6. 在页面使用js回车键

    网上有大量的文章关于 js回车事件的,但是只有适合自己的才是最好的. 第一种: // submit closest form $(".keydown_submit").keydow ...

  7. DataTable扩展方法ToList<T>()、ToJSON()、ToArrayList()

    /// <summary> /// 扩展方法类 /// </summary> public static class CommonExtension { /// <sum ...

  8. canvas初探1

    刚申请的博客,当然这也是第一篇.对于canvas也是刚开始着手进行学习,有哪些不对的地方,还望看到本篇博文的朋友指正. 1.canvas的历史 首先,它是HTML5的一个标签. 它是为了客户端矢量图形 ...

  9. HDFS 架构解析

    本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...

  10. Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用

    一.高可用的Session服务器场景简介 1.1 应用服务器的无状态特性 应用层服务器(这里一般指Web服务器)处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性. PS:提到无状态特性 ...