【Win 10应用开发】多窗口视图
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应用开发】多窗口视图的更多相关文章
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- 【Win 10 应用开发】导入.pfx证书
这个功能其实并不常用,一般开发较少涉及到证书,不过,简单了解一下还是有必要的. 先来说说制作测试证书的方法,这里老周讲两种方法,可以生成用于测试的.pfx文件. 产生证书,大家都知道有个makecer ...
- 【Win 10应用开发】Adaptive磁贴模板的XML文档结构
在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴的新XML模板. 同样道理,你依旧可以使用8.1时候的磁贴模板,在win ...
- 【Win 10应用开发】认识一下UAP项目
Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...
- 【Win 10 应用开发】RTM版的UAP项目解剖
Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...
- 【Win 10 应用开发】在代码中加载文本资源
记得前一次,老周给大伙,不,小伙伴们介绍了如何填写 .resw 文件,并且在 XAML 中使用 x:Uid 标记来加载.也顺便给大伙儿分析了运行时是如何解析 .resw 文件的. 本来说好了,后续老周 ...
- 【Win 10应用开发】延迟共享
延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...
- 【Win 10 应用开发】Toast通知激活应用——前台&后台
老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...
- 【Win 10 应用开发】UI Composition 札记(一):视图框架的实现
在开始今天的内容之前,老周先说一个问题,这个问题记得以前有人提过的. 设置 Windows.ApplicationModel.Core.CoreApplicationView.TitleBar.Ext ...
随机推荐
- BZOJ4742 : [Usaco2016 Dec]Team Building
如果我们将两个人拥有的牛混在一起,并按照战斗力从小到大排序,同时把第一个人选的牛看成$)$,第二个人选的牛看成$($的话,那么我们会发现一个合法的方案对应了一个长度为$2k$的括号序列. 于是DP即可 ...
- 【系统篇】从int 3探索Windows应用程序调试原理
探索调试器下断点的原理 在Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的时候会中断到调试器,如果程 ...
- WCF服务编程
WCF服务编程, 我是WCF的初学者,在这想分享学习WCF服务编程的过程,欢迎大家多多指教!
- 软件工程:黄金G点小游戏1.0
我们要做的是黄金G点小游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值. ...
- 使用git把项目提交到github
1.需要在https://github.com/注册一个账户 2.注册成功后,新建一个repository,用来存放你要上传的项目,如下图所示 这里你需要输入你的项目的名称,可以对你的项目进行描述,如 ...
- win32进程名查找进程PID
1. #include <Psapi.h> #pragma comment(lib, "Psapi.lib") DWORD GetProcIDFromName(LPCT ...
- php 图片上传的公共方法(按图片宽高缩放或原图)
写的用于图片上传的公共方法类调用方法: $upload_name='pic';$type = 'logo_val';$file_name = 'logo_' . $user_id .create_st ...
- advstringgrid笔记
一下操作是在advstringgrid7.4.6.3版本下有效,advstringgrid控件名设置为 zy 一.属性设置 1.修改单元格内的值:zy.cells[col,row]='value'; ...
- 参加MVP OpenDay 和2015 MVP Community Camp社区大课堂
微软MVP Openday 1月30日在北京召开,到时全国上百位 MVP 专家将齐聚北京.当然还有亚太的其他国家地区的MVP 也会来北京,1月31日微软 MVP 项目组主办的年度微软技术社区分享大会- ...
- APP漏洞扫描器之本地拒绝服务检测详解
APP漏洞扫描器之本地拒绝服务检测详解 阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面.本文将讲一下应用漏洞 ...