UI: 多窗口
1、自定义帮助类,用于简化 SecondaryView 的管理
UI/MultipleViews/SecondaryViewHelper.cs

- /*
- * SecondaryViewHelper - 自定义的一个帮助类,用于简化 SecondaryView 的管理
- */
- using System;
- using System.ComponentModel;
- using Windows.UI.Core;
- using Windows.UI.ViewManagement;
- namespace Windows10.UI.MultipleViews
- {
- public class SecondaryViewHelper : INotifyPropertyChanged
- {
- // for INotifyPropertyChanged
- public event PropertyChangedEventHandler PropertyChanged;
- // 当前 SecondaryView 的 CoreDispatcher
- private CoreDispatcher _dispatcher;
- // 当前 SecondaryView 的 ApplicationView
- private ApplicationView _applicationView;
- // 当前 SecondaryView 的标题
- private string _title;
- // 当前 SecondaryView 的窗口标识
- private int _viewId;
- // 当前 SecondaryView 被引用的次数
- private int _refCount = 0;
- // 当前 SecondaryView 是否已经被释放
- private bool _released = false;
- // 禁止通过 new 实例化
- private SecondaryViewHelper(CoreWindow newWindow)
- {
- _dispatcher = newWindow.Dispatcher;
- _viewId = ApplicationView.GetApplicationViewIdForWindow(newWindow);
- _applicationView = ApplicationView.GetForCurrentView();
- RegisterForEvents();
- }
- // 实例化 SecondaryViewHelper
- public static SecondaryViewHelper CreateForCurrentView()
- {
- /*
- * CoreWindow.GetForCurrentThread() - 获取当前窗口的 CoreWindow
- */
- return new SecondaryViewHelper(CoreWindow.GetForCurrentThread());
- }
- private void RegisterForEvents()
- {
- /*
- * ApplicationView.GetForCurrentView() - 获取当前窗口的 ApplicationView
- * ApplicationView.Consolidated - 当前 app 存活着两个或两个以上的窗口时,此窗口关闭后触发的事件
- */
- ApplicationView.GetForCurrentView().Consolidated += SecondaryViewHelper_Consolidated;
- }
- private void UnregisterForEvents()
- {
- ApplicationView.GetForCurrentView().Consolidated -= SecondaryViewHelper_Consolidated;
- }
- private void SecondaryViewHelper_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
- {
- StopViewInUse();
- }
- // 当前 SecondaryView 开始使用了(与 StopViewInUse() 成对)
- // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
- public int StartViewInUse()
- {
- bool releasedCopy = false;
- int refCountCopy = 0;
- lock (this)
- {
- releasedCopy =_released;
- if (!_released)
- {
- refCountCopy = ++_refCount;
- }
- }
- if (releasedCopy)
- {
- throw new InvalidOperationException("this view is being disposed");
- }
- return refCountCopy;
- }
- // 当前 SecondaryView 结束使用了(与 StartViewInUse() 成对)
- // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
- public int StopViewInUse()
- {
- int refCountCopy = 0;
- bool releasedCopy = false;
- lock (this)
- {
- releasedCopy = _released;
- if (!_released)
- {
- refCountCopy = --_refCount;
- if (refCountCopy == 0)
- {
- // 当前 SecondaryView 不再被任何人需要了,清理之
- var task = _dispatcher.RunAsync(CoreDispatcherPriority.Low, FinalizeRelease);
- }
- }
- }
- if (releasedCopy)
- {
- throw new InvalidOperationException("this view is being disposed");
- }
- return refCountCopy;
- }
- // 清理当前 SecondaryView
- private void FinalizeRelease()
- {
- bool justReleased = false;
- lock (this)
- {
- if (_refCount == 0)
- {
- justReleased = true;
- _released = true;
- }
- }
- if (justReleased)
- {
- UnregisterForEvents();
- // 触发 Released 事件
- OnReleased(EventArgs.Empty);
- }
- }
- // 定义 Released 事件
- public event EventHandler<EventArgs> Released;
- protected virtual void OnReleased(EventArgs e)
- {
- EventHandler<EventArgs> handler = Released;
- if (handler != null)
- handler(this, e);
- }
- public int Id
- {
- get
- {
- return _viewId;
- }
- }
- public string Title
- {
- get
- {
- return _title;
- }
- set
- {
- if (_title != value)
- {
- _title = value;
- if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(nameof(Title)));
- }
- }
- }
- }
- public bool IsReleased
- {
- get
- {
- return _released;
- }
- }
- public ApplicationView ApplicationView
- {
- get
- {
- return _applicationView;
- }
- }
- }
- }

2、扩展 Application 对象,定义一些需要用到的全局变量
UI/MultipleViews/AppPartial.cs

- /*
- * 扩展 Application 对象,定义一些需要用到的全局变量
- */
- using Windows.ApplicationModel.Activation;
- using Windows.UI.Core;
- using Windows.UI.ViewManagement;
- using Windows.UI.Xaml;
- using Windows.UI.Xaml.Controls;
- namespace Windows10
- {
- public partial class App
- {
- // PrimaryView 的 CoreDispatcher
- private CoreDispatcher _mainDispatcher;
- // PrimaryView 的窗口标识
- private int _mainViewId;
- // partial method,实现了 App.xaml.cs 中的声明
- partial void OnLaunched_MultipleViews(LaunchActivatedEventArgs args)
- {
- _mainDispatcher = Window.Current.Dispatcher;
- _mainViewId = ApplicationView.GetForCurrentView().Id;
- }
- public CoreDispatcher MainDispatcher
- {
- get
- {
- return _mainDispatcher;
- }
- }
- public int MainViewId
- {
- get
- {
- return _mainViewId;
- }
- }
- }
- }

3、用于演示 SecondaryView 的示例
UI/MultipleViews/SecondaryViewPage.xaml

- <Page
- x:Class="Windows10.UI.MultipleViews.SecondaryViewPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="using:Windows10.UI.MultipleViews"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d">
- <Grid Background="Transparent">
- <StackPanel Margin="10 0 10 10">
- <TextBlock Name="lblMsg" Margin="0 10 0 0" />
- <Button Name="btnGoToMain" Content="切换到主窗口" Click="btnGoToMain_Click" Margin="0 10 0 0" />
- <Button Name="btnGoToMainAndHideThisView" Content="切换到主窗口,并关闭此窗口" Click="btnGoToMainAndHideThisView_Click" Margin="0 10 0 0" />
- </StackPanel>
- </Grid>
- </Page>

UI/MultipleViews/SecondaryViewPage.xaml.cs

- /*
- * 演示“多窗口”相关知识点。本页是 SecondaryView
- */
- using System;
- using System.ComponentModel;
- using Windows.ApplicationModel.Core;
- using Windows.UI.Core;
- using Windows.UI.ViewManagement;
- using Windows.UI.Xaml;
- using Windows.UI.Xaml.Controls;
- using Windows.UI.Xaml.Navigation;
- namespace Windows10.UI.MultipleViews
- {
- public sealed partial class SecondaryViewPage : Page
- {
- private SecondaryViewHelper _secondaryViewHelper;
- public SecondaryViewPage()
- {
- this.InitializeComponent();
- }
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- _secondaryViewHelper = (SecondaryViewHelper)e.Parameter;
- _secondaryViewHelper.Released += _secondaryViewHelper_Released;
- // 设置当前窗口的 Title
- ApplicationView.GetForCurrentView().Title = _secondaryViewHelper.Title;
- _secondaryViewHelper.PropertyChanged += _secondaryViewHelper_PropertyChanged;
- }
- private void _secondaryViewHelper_PropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(_secondaryViewHelper.Title))
- {
- _secondaryViewHelper.ApplicationView.Title = _secondaryViewHelper.Title;
- }
- }
- private async void _secondaryViewHelper_Released(object sender, EventArgs e)
- {
- ((SecondaryViewHelper)sender).Released -= _secondaryViewHelper_Released;
- await ((App)App.Current).MainDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
- {
- // 调用主窗口线程,执行逻辑
- });
- Window.Current.Close();
- }
- private async void btnGoToMain_Click(object sender, RoutedEventArgs e)
- {
- _secondaryViewHelper.StartViewInUse();
- /*
- * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
- */
- await ApplicationViewSwitcher.SwitchAsync
- (
- ((App)App.Current).MainViewId // 准备显示的窗口的 id
- );
- _secondaryViewHelper.StopViewInUse();
- }
- private async void btnGoToMainAndHideThisView_Click(object sender, RoutedEventArgs e)
- {
- _secondaryViewHelper.StartViewInUse();
- /*
- * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
- */
- await ApplicationViewSwitcher.SwitchAsync
- (
- ((App)App.Current).MainViewId, // 准备显示的窗口的 id
- ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
- ApplicationViewSwitchingOptions.ConsolidateViews // 切换行为选项(Default - 标准动画切换; SkipAnimation - 不使用动画切换; ConsolidateViews - 切换后关闭调用者窗口)
- );
- _secondaryViewHelper.StopViewInUse();
- }
- }
- }

4、用于演示 PrimaryView 的示例
UI/MultipleViews/Demo.xaml

- <Page
- x:Class="Windows10.UI.MultipleViews.Demo"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="using:Windows10.UI.MultipleViews"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d">
- <Grid Background="Transparent">
- <StackPanel Margin="10 0 10 10">
- <TextBlock Name="lblMsg" Margin="0 10 0 0" />
- <Button Name="btnShow" Content="创建并显示一个新的窗口" Click="btnShow_Click" Margin="0 10 0 0" />
- <Button Name="btnChangeLastSecondaryViewTitle" Content="修改最近一个被我打开的 SecondaryView 的 Title" Click="btnChangeLastSecondaryViewTitle_Click" Margin="0 10 0 0" />
- </StackPanel>
- </Grid>
- </Page>

UI/MultipleViews/Demo.xaml.cs

- /*
- * 演示“多窗口”相关知识点。本页是 PrimaryView
- *
- *
- * 解释一下本例中用于说明的几个名词:PrimaryView - 主窗口; SecondaryView - 新开窗口
- */
- using System;
- using Windows.ApplicationModel.Core;
- using Windows.UI.Core;
- using Windows.UI.ViewManagement;
- using Windows.UI.Xaml;
- using Windows.UI.Xaml.Controls;
- namespace Windows10.UI.MultipleViews
- {
- public sealed partial class Demo : Page
- {
- // 自定义的用于简化 SecondaryView 管理的帮助类
- SecondaryViewHelper _secondaryViewHelper = null;
- public Demo()
- {
- this.InitializeComponent();
- this.Loaded += Demo_Loaded;
- }
- private void Demo_Loaded(object sender, RoutedEventArgs e)
- {
- ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
- }
- private async void btnShow_Click(object sender, RoutedEventArgs e)
- {
- /*
- * CoreApplication.CreateNewView() - 创建一个新的 SecondaryView(只是新建一个 SecondaryView 实例,并不会显示出来)
- */
- await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
- {
- _secondaryViewHelper = SecondaryViewHelper.CreateForCurrentView();
- _secondaryViewHelper.Title = "i am secondary view";
- _secondaryViewHelper.StartViewInUse();
- var frame = new Frame();
- frame.Navigate(typeof(SecondaryViewPage), _secondaryViewHelper);
- Window.Current.Content = frame;
- Window.Current.Activate();
- // 这里通过 ApplicationView.GetForCurrentView() 获取到的是新开窗口的 ApplicationView 对象
- ApplicationView secondaryView = ApplicationView.GetForCurrentView();
- });
- try
- {
- _secondaryViewHelper.StartViewInUse();
- /*
- * ApplicationViewSwitcher.TryShowAsStandaloneAsync() - 在当前窗口的相邻位置显示另一个窗口
- */
- ApplicationViewSwitcher.DisableShowingMainViewOnActivation();
- var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync
- (
- _secondaryViewHelper.Id, // 需要显示的 SecondaryView 的窗口 id
- ViewSizePreference.Default, // 需要显示的 SecondaryView 的尺寸首选项(经测试,此参数无效)
- ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
- ViewSizePreference.Default // 调用者的尺寸首选项(经测试,此参数无效)
- );
- if (!viewShown)
- {
- lblMsg.Text = "显示 SecondaryView 失败";
- }
- _secondaryViewHelper.StopViewInUse();
- }
- catch (Exception ex)
- {
- lblMsg.Text = ex.ToString();
- }
- }
- // 修改最近一个被我打开的 SecondaryView 的 Title
- private void btnChangeLastSecondaryViewTitle_Click(object sender, RoutedEventArgs e)
- {
- if (_secondaryViewHelper != null && !_secondaryViewHelper.IsReleased)
- _secondaryViewHelper.Title = new Random().Next().ToString();
- }
- }
- }

UI: 多窗口的更多相关文章
- 背水一战 Windows 10 (4) - UI: 多窗口
[源码下载] 背水一战 Windows 10 (4) - UI: 多窗口 作者:webabcd 介绍背水一战 Windows 10 之 UI 多窗口 示例1.自定义帮助类,用于简化 Secondary ...
- Win10 UI入门窗口由默认500px to 320px
https://code.msdn.microsoft.com/Layout-for-windows-that-ba648e1c/ https://msdn.microsoft.com/library ...
- 【Qt编程】Qt学习之窗口间的相互切换
在用Qt设计GUI时,经常要设计两个窗口之间的相互切换,即可以从一个窗口跳转到另一个窗口,然后又从另一个窗口跳转回原窗口.下面我们来介绍具体的实现方法: 工程建立及功能描述: 首先,我们建立Qt G ...
- c# winform 应用程序根据条件阻止窗口关闭
//添加窗口关闭事件委托 在窗口关闭事件中处理 private void TestForm_FormClosing(object sender, FormClosingEventArgs e) { s ...
- Qt 使用QLabel、QMovie加载gif图片实现动态等待窗口
新建基于Widget的应用程序,在ui的窗口中添加QLabel,对象名label,调整整个窗口大小. 准备loading.gif图片 Widget.cpp 12345678910111213141 ...
- 10、堆叠窗口StackedWidget
新建项目,基类选择QMainWindow,勾选ui 堆叠窗口有三个page,每个page有个label button处,快捷菜单,转到槽,添加代码 void MainWindow::on_push ...
- MFC单文档视图中嵌入GLFW窗口
开始学习OpenGL由于有一段时间,但是glfw只有窗口区,虽然通过某种手段(移步这里)可以加入工具栏,但仍然无法作为一个标准的GUI,而直接在MFC或Qt里面使用OpenGL API感觉有诸多制肘, ...
- qt之串口
qt串口讲解在QT中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也使用这个 ...
- 【UGUI】Canvas和Rect Transform
Canvas 1.所有的UI元件都需要放在Canvas里 2.UI元件的绘制顺序,与在 Hierarchy的顺序相同,在上面的元素会先被绘制,位于后续绘制元素的下面 3.可以选择3种不同的渲染模式: ...
随机推荐
- Ajax中Get请求与Post请求的区别
Get请求和Post请求的区别 1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来 2.使用Get请求发送数据量小,Post请求发送数据量大 例子 页面的HTML代码: &l ...
- BCP笔记整理(二)
BCP的基础用法可以参考上一篇:http://www.cnblogs.com/Gin-23333/p/5489889.html 这篇是补充一些有可能会用到,但是出场几率并不算大的几个参数 1.首先是 ...
- mongo学习笔记(一):增删改查
安装:我是按这篇来弄的 一.Insert 1.db.person.insert({"name":"jack","age":20}) 2.va ...
- SQL数据库修改默认备份和恢复路径
每次都做数据恢复和备份的时候,点Add文件,系统会自动指定到一个默认路径,是SQL的安装目录,但是我的数据库不是备份在这里,每次都要更改有点麻烦. 如上图,更改这个有三个方法. 方法一:找到注册表,手 ...
- C++智能指针详解
本文出自http://mxdxm.iteye.com/ 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最 ...
- SCCM 2012 R2安装部署过程和问题(一)
在进行Windows Server 2012 R2虚拟化测试前,由于需要安装,部署和管理很多的服务器,自然会想到该如何提高效率和有效的管理.在Windows Server 2008的时代微软已经提供称 ...
- 去掉windows8.1鸡肋的开始按钮
无开始按钮了,win8.1的 开始按钮反而非常鸡肋.. 可以使用我分享的链接下载startisgone: http://download.csdn.net/detail/wangallan/89728 ...
- Android Studio failed to open by giving error “Files Locked” 解决方案
windows 7 下的解决方案 导航至 android-studio 安装目录. (默认为C:\Program Files (x86)\Android\android-studio). 往上一层文件 ...
- WPF系列-CheckBox
自定义样式1 效果: 代码: <!-- CheckBox的样式 --> <Style TargetType="{x:Type CheckBox}"> < ...
- 使用Vmware虚拟机部署开发环境之Mac OS X系统安装
一.使用VMware虚拟机部署Swift开发环境所需工具: Vmware Workstation 10.0虚拟机软件 VM安装Mac解锁工具Unlock 苹果操作系统(Mac OS X Maveric ...