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

  1. /*
  2. * SecondaryViewHelper - 自定义的一个帮助类,用于简化 SecondaryView 的管理
  3. */
  4.  
  5. using System;
  6. using System.ComponentModel;
  7. using Windows.UI.Core;
  8. using Windows.UI.ViewManagement;
  9.  
  10. namespace Windows10.UI.MultipleViews
  11. {
  12. public class SecondaryViewHelper : INotifyPropertyChanged
  13. {
  14. // for INotifyPropertyChanged
  15. public event PropertyChangedEventHandler PropertyChanged;
  16.  
  17. // 当前 SecondaryView 的 CoreDispatcher
  18. private CoreDispatcher _dispatcher;
  19. // 当前 SecondaryView 的 ApplicationView
  20. private ApplicationView _applicationView;
  21.  
  22. // 当前 SecondaryView 的标题
  23. private string _title;
  24. // 当前 SecondaryView 的窗口标识
  25. private int _viewId;
  26.  
  27. // 当前 SecondaryView 被引用的次数
  28. private int _refCount = 0;
  29. // 当前 SecondaryView 是否已经被释放
  30. private bool _released = false;
  31.  
  32. // 禁止通过 new 实例化
  33. private SecondaryViewHelper(CoreWindow newWindow)
  34. {
  35. _dispatcher = newWindow.Dispatcher;
  36. _viewId = ApplicationView.GetApplicationViewIdForWindow(newWindow);
  37.  
  38. _applicationView = ApplicationView.GetForCurrentView();
  39.  
  40. RegisterForEvents();
  41. }
  42.  
  43. // 实例化 SecondaryViewHelper
  44. public static SecondaryViewHelper CreateForCurrentView()
  45. {
  46. /*
  47. * CoreWindow.GetForCurrentThread() - 获取当前窗口的 CoreWindow
  48. */
  49. return new SecondaryViewHelper(CoreWindow.GetForCurrentThread());
  50. }
  51. private void RegisterForEvents()
  52. {
  53. /*
  54. * ApplicationView.GetForCurrentView() - 获取当前窗口的 ApplicationView
  55. * ApplicationView.Consolidated - 当前 app 存活着两个或两个以上的窗口时,此窗口关闭后触发的事件
  56. */
  57. ApplicationView.GetForCurrentView().Consolidated += SecondaryViewHelper_Consolidated;
  58. }
  59.  
  60. private void UnregisterForEvents()
  61. {
  62. ApplicationView.GetForCurrentView().Consolidated -= SecondaryViewHelper_Consolidated;
  63. }
  64.  
  65. private void SecondaryViewHelper_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
  66. {
  67. StopViewInUse();
  68. }
  69.  
  70. // 当前 SecondaryView 开始使用了(与 StopViewInUse() 成对)
  71. // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
  72. public int StartViewInUse()
  73. {
  74. bool releasedCopy = false;
  75. int refCountCopy = 0;
  76.  
  77. lock (this)
  78. {
  79. releasedCopy =_released;
  80. if (!_released)
  81. {
  82. refCountCopy = ++_refCount;
  83. }
  84. }
  85.  
  86. if (releasedCopy)
  87. {
  88. throw new InvalidOperationException("this view is being disposed");
  89. }
  90.  
  91. return refCountCopy;
  92. }
  93.  
  94. // 当前 SecondaryView 结束使用了(与 StartViewInUse() 成对)
  95. // 因为每一个窗口都可以被同 app 的别的窗口调用,而每一个窗口又都是一个独立的线程,所以要做好线程处理
  96. public int StopViewInUse()
  97. {
  98. int refCountCopy = 0;
  99. bool releasedCopy = false;
  100.  
  101. lock (this)
  102. {
  103. releasedCopy = _released;
  104. if (!_released)
  105. {
  106. refCountCopy = --_refCount;
  107. if (refCountCopy == 0)
  108. {
  109. // 当前 SecondaryView 不再被任何人需要了,清理之
  110. var task = _dispatcher.RunAsync(CoreDispatcherPriority.Low, FinalizeRelease);
  111. }
  112. }
  113. }
  114.  
  115. if (releasedCopy)
  116. {
  117. throw new InvalidOperationException("this view is being disposed");
  118. }
  119.  
  120. return refCountCopy;
  121. }
  122.  
  123. // 清理当前 SecondaryView
  124. private void FinalizeRelease()
  125. {
  126. bool justReleased = false;
  127. lock (this)
  128. {
  129. if (_refCount == 0)
  130. {
  131. justReleased = true;
  132. _released = true;
  133. }
  134. }
  135.  
  136. if (justReleased)
  137. {
  138. UnregisterForEvents();
  139.  
  140. // 触发 Released 事件
  141. OnReleased(EventArgs.Empty);
  142. }
  143. }
  144.  
  145. // 定义 Released 事件
  146. public event EventHandler<EventArgs> Released;
  147. protected virtual void OnReleased(EventArgs e)
  148. {
  149. EventHandler<EventArgs> handler = Released;
  150. if (handler != null)
  151. handler(this, e);
  152. }
  153.  
  154. public int Id
  155. {
  156. get
  157. {
  158. return _viewId;
  159. }
  160. }
  161.  
  162. public string Title
  163. {
  164. get
  165. {
  166. return _title;
  167. }
  168. set
  169. {
  170. if (_title != value)
  171. {
  172. _title = value;
  173.  
  174. if (PropertyChanged != null)
  175. {
  176. PropertyChanged(this, new PropertyChangedEventArgs(nameof(Title)));
  177. }
  178. }
  179. }
  180. }
  181.  
  182. public bool IsReleased
  183. {
  184. get
  185. {
  186. return _released;
  187. }
  188. }
  189.  
  190. public ApplicationView ApplicationView
  191. {
  192. get
  193. {
  194. return _applicationView;
  195. }
  196. }
  197. }
  198. }

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

  1. /*
  2. * 扩展 Application 对象,定义一些需要用到的全局变量
  3. */
  4.  
  5. using Windows.ApplicationModel.Activation;
  6. using Windows.UI.Core;
  7. using Windows.UI.ViewManagement;
  8. using Windows.UI.Xaml;
  9. using Windows.UI.Xaml.Controls;
  10.  
  11. namespace Windows10
  12. {
  13. public partial class App
  14. {
  15. // PrimaryView 的 CoreDispatcher
  16. private CoreDispatcher _mainDispatcher;
  17. // PrimaryView 的窗口标识
  18. private int _mainViewId;
  19.  
  20. // partial method,实现了 App.xaml.cs 中的声明
  21. partial void OnLaunched_MultipleViews(LaunchActivatedEventArgs args)
  22. {
  23. _mainDispatcher = Window.Current.Dispatcher;
  24. _mainViewId = ApplicationView.GetForCurrentView().Id;
  25. }
  26.  
  27. public CoreDispatcher MainDispatcher
  28. {
  29. get
  30. {
  31. return _mainDispatcher;
  32. }
  33. }
  34.  
  35. public int MainViewId
  36. {
  37. get
  38. {
  39. return _mainViewId;
  40. }
  41. }
  42. }
  43. }

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

  1. <Page
  2. x:Class="Windows10.UI.MultipleViews.SecondaryViewPage"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:Windows10.UI.MultipleViews"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Grid Background="Transparent">
  11. <StackPanel Margin="10 0 10 10">
  12.  
  13. <TextBlock Name="lblMsg" Margin="0 10 0 0" />
  14.  
  15. <Button Name="btnGoToMain" Content="切换到主窗口" Click="btnGoToMain_Click" Margin="0 10 0 0" />
  16.  
  17. <Button Name="btnGoToMainAndHideThisView" Content="切换到主窗口,并关闭此窗口" Click="btnGoToMainAndHideThisView_Click" Margin="0 10 0 0" />
  18.  
  19. </StackPanel>
  20. </Grid>
  21. </Page>

UI/MultipleViews/SecondaryViewPage.xaml.cs

  1. /*
  2. * 演示“多窗口”相关知识点。本页是 SecondaryView
  3. */
  4.  
  5. using System;
  6. using System.ComponentModel;
  7. using Windows.ApplicationModel.Core;
  8. using Windows.UI.Core;
  9. using Windows.UI.ViewManagement;
  10. using Windows.UI.Xaml;
  11. using Windows.UI.Xaml.Controls;
  12. using Windows.UI.Xaml.Navigation;
  13.  
  14. namespace Windows10.UI.MultipleViews
  15. {
  16. public sealed partial class SecondaryViewPage : Page
  17. {
  18. private SecondaryViewHelper _secondaryViewHelper;
  19.  
  20. public SecondaryViewPage()
  21. {
  22. this.InitializeComponent();
  23. }
  24.  
  25. protected override void OnNavigatedTo(NavigationEventArgs e)
  26. {
  27. _secondaryViewHelper = (SecondaryViewHelper)e.Parameter;
  28. _secondaryViewHelper.Released += _secondaryViewHelper_Released;
  29.  
  30. // 设置当前窗口的 Title
  31. ApplicationView.GetForCurrentView().Title = _secondaryViewHelper.Title;
  32. _secondaryViewHelper.PropertyChanged += _secondaryViewHelper_PropertyChanged;
  33. }
  34.  
  35. private void _secondaryViewHelper_PropertyChanged(object sender, PropertyChangedEventArgs e)
  36. {
  37. if (e.PropertyName == nameof(_secondaryViewHelper.Title))
  38. {
  39. _secondaryViewHelper.ApplicationView.Title = _secondaryViewHelper.Title;
  40. }
  41. }
  42.  
  43. private async void _secondaryViewHelper_Released(object sender, EventArgs e)
  44. {
  45. ((SecondaryViewHelper)sender).Released -= _secondaryViewHelper_Released;
  46.  
  47. await ((App)App.Current).MainDispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  48. {
  49. // 调用主窗口线程,执行逻辑
  50. });
  51.  
  52. Window.Current.Close();
  53. }
  54.  
  55. private async void btnGoToMain_Click(object sender, RoutedEventArgs e)
  56. {
  57. _secondaryViewHelper.StartViewInUse();
  58.  
  59. /*
  60. * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
  61. */
  62. await ApplicationViewSwitcher.SwitchAsync
  63. (
  64. ((App)App.Current).MainViewId // 准备显示的窗口的 id
  65. );
  66.  
  67. _secondaryViewHelper.StopViewInUse();
  68. }
  69.  
  70. private async void btnGoToMainAndHideThisView_Click(object sender, RoutedEventArgs e)
  71. {
  72. _secondaryViewHelper.StartViewInUse();
  73.  
  74. /*
  75. * ApplicationViewSwitcher.SwitchAsync() - 切换到指定的窗口
  76. */
  77. await ApplicationViewSwitcher.SwitchAsync
  78. (
  79. ((App)App.Current).MainViewId, // 准备显示的窗口的 id
  80. ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
  81. ApplicationViewSwitchingOptions.ConsolidateViews // 切换行为选项(Default - 标准动画切换; SkipAnimation - 不使用动画切换; ConsolidateViews - 切换后关闭调用者窗口)
  82. );
  83.  
  84. _secondaryViewHelper.StopViewInUse();
  85. }
  86. }
  87. }

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

  1. <Page
  2. x:Class="Windows10.UI.MultipleViews.Demo"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:Windows10.UI.MultipleViews"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Grid Background="Transparent">
  11. <StackPanel Margin="10 0 10 10">
  12.  
  13. <TextBlock Name="lblMsg" Margin="0 10 0 0" />
  14.  
  15. <Button Name="btnShow" Content="创建并显示一个新的窗口" Click="btnShow_Click" Margin="0 10 0 0" />
  16.  
  17. <Button Name="btnChangeLastSecondaryViewTitle" Content="修改最近一个被我打开的 SecondaryView 的 Title" Click="btnChangeLastSecondaryViewTitle_Click" Margin="0 10 0 0" />
  18.  
  19. </StackPanel>
  20. </Grid>
  21. </Page>

UI/MultipleViews/Demo.xaml.cs

  1. /*
  2. * 演示“多窗口”相关知识点。本页是 PrimaryView
  3. *
  4. *
  5. * 解释一下本例中用于说明的几个名词:PrimaryView - 主窗口; SecondaryView - 新开窗口
  6. */
  7.  
  8. using System;
  9. using Windows.ApplicationModel.Core;
  10. using Windows.UI.Core;
  11. using Windows.UI.ViewManagement;
  12. using Windows.UI.Xaml;
  13. using Windows.UI.Xaml.Controls;
  14.  
  15. namespace Windows10.UI.MultipleViews
  16. {
  17. public sealed partial class Demo : Page
  18. {
  19. // 自定义的用于简化 SecondaryView 管理的帮助类
  20. SecondaryViewHelper _secondaryViewHelper = null;
  21.  
  22. public Demo()
  23. {
  24. this.InitializeComponent();
  25.  
  26. this.Loaded += Demo_Loaded;
  27. }
  28.  
  29. private void Demo_Loaded(object sender, RoutedEventArgs e)
  30. {
  31. ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
  32. }
  33.  
  34. private async void btnShow_Click(object sender, RoutedEventArgs e)
  35. {
  36. /*
  37. * CoreApplication.CreateNewView() - 创建一个新的 SecondaryView(只是新建一个 SecondaryView 实例,并不会显示出来)
  38. */
  39. await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
  40. {
  41. _secondaryViewHelper = SecondaryViewHelper.CreateForCurrentView();
  42. _secondaryViewHelper.Title = "i am secondary view";
  43.  
  44. _secondaryViewHelper.StartViewInUse();
  45.  
  46. var frame = new Frame();
  47. frame.Navigate(typeof(SecondaryViewPage), _secondaryViewHelper);
  48. Window.Current.Content = frame;
  49. Window.Current.Activate();
  50.  
  51. // 这里通过 ApplicationView.GetForCurrentView() 获取到的是新开窗口的 ApplicationView 对象
  52. ApplicationView secondaryView = ApplicationView.GetForCurrentView();
  53. });
  54.  
  55. try
  56. {
  57. _secondaryViewHelper.StartViewInUse();
  58.  
  59. /*
  60. * ApplicationViewSwitcher.TryShowAsStandaloneAsync() - 在当前窗口的相邻位置显示另一个窗口
  61. */
  62. ApplicationViewSwitcher.DisableShowingMainViewOnActivation();
  63. var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync
  64. (
  65. _secondaryViewHelper.Id, // 需要显示的 SecondaryView 的窗口 id
  66. ViewSizePreference.Default, // 需要显示的 SecondaryView 的尺寸首选项(经测试,此参数无效)
  67. ApplicationView.GetForCurrentView().Id, // 调用者的窗口 id
  68. ViewSizePreference.Default // 调用者的尺寸首选项(经测试,此参数无效)
  69. );
  70.  
  71. if (!viewShown)
  72. {
  73. lblMsg.Text = "显示 SecondaryView 失败";
  74. }
  75.  
  76. _secondaryViewHelper.StopViewInUse();
  77. }
  78. catch (Exception ex)
  79. {
  80. lblMsg.Text = ex.ToString();
  81. }
  82. }
  83.  
  84. // 修改最近一个被我打开的 SecondaryView 的 Title
  85. private void btnChangeLastSecondaryViewTitle_Click(object sender, RoutedEventArgs e)
  86. {
  87. if (_secondaryViewHelper != null && !_secondaryViewHelper.IsReleased)
  88. _secondaryViewHelper.Title = new Random().Next().ToString();
  89. }
  90. }
  91. }

UI: 多窗口的更多相关文章

  1. 背水一战 Windows 10 (4) - UI: 多窗口

    [源码下载] 背水一战 Windows 10 (4) - UI: 多窗口 作者:webabcd 介绍背水一战 Windows 10 之 UI 多窗口 示例1.自定义帮助类,用于简化 Secondary ...

  2. Win10 UI入门窗口由默认500px to 320px

    https://code.msdn.microsoft.com/Layout-for-windows-that-ba648e1c/ https://msdn.microsoft.com/library ...

  3. 【Qt编程】Qt学习之窗口间的相互切换

    在用Qt设计GUI时,经常要设计两个窗口之间的相互切换,即可以从一个窗口跳转到另一个窗口,然后又从另一个窗口跳转回原窗口.下面我们来介绍具体的实现方法: 工程建立及功能描述: 首先,我们建立Qt  G ...

  4. c# winform 应用程序根据条件阻止窗口关闭

    //添加窗口关闭事件委托 在窗口关闭事件中处理 private void TestForm_FormClosing(object sender, FormClosingEventArgs e) { s ...

  5. Qt 使用QLabel、QMovie加载gif图片实现动态等待窗口

    新建基于Widget的应用程序,在ui的窗口中添加QLabel,对象名label,调整整个窗口大小. 准备loading.gif图片  Widget.cpp  12345678910111213141 ...

  6. 10、堆叠窗口StackedWidget

    新建项目,基类选择QMainWindow,勾选ui 堆叠窗口有三个page,每个page有个label   button处,快捷菜单,转到槽,添加代码 void MainWindow::on_push ...

  7. MFC单文档视图中嵌入GLFW窗口

    开始学习OpenGL由于有一段时间,但是glfw只有窗口区,虽然通过某种手段(移步这里)可以加入工具栏,但仍然无法作为一个标准的GUI,而直接在MFC或Qt里面使用OpenGL API感觉有诸多制肘, ...

  8. qt之串口

                                          qt串口讲解在QT中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也使用这个 ...

  9. 【UGUI】Canvas和Rect Transform

    Canvas 1.所有的UI元件都需要放在Canvas里 2.UI元件的绘制顺序,与在 Hierarchy的顺序相同,在上面的元素会先被绘制,位于后续绘制元素的下面 3.可以选择3种不同的渲染模式: ...

随机推荐

  1. Ajax中Get请求与Post请求的区别

    Get请求和Post请求的区别 1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来 2.使用Get请求发送数据量小,Post请求发送数据量大 例子 页面的HTML代码: &l ...

  2. BCP笔记整理(二)

    BCP的基础用法可以参考上一篇:http://www.cnblogs.com/Gin-23333/p/5489889.html 这篇是补充一些有可能会用到,但是出场几率并不算大的几个参数 1.首先是 ...

  3. mongo学习笔记(一):增删改查

    安装:我是按这篇来弄的 一.Insert 1.db.person.insert({"name":"jack","age":20}) 2.va ...

  4. SQL数据库修改默认备份和恢复路径

    每次都做数据恢复和备份的时候,点Add文件,系统会自动指定到一个默认路径,是SQL的安装目录,但是我的数据库不是备份在这里,每次都要更改有点麻烦. 如上图,更改这个有三个方法. 方法一:找到注册表,手 ...

  5. C++智能指针详解

    本文出自http://mxdxm.iteye.com/ 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最 ...

  6. SCCM 2012 R2安装部署过程和问题(一)

    在进行Windows Server 2012 R2虚拟化测试前,由于需要安装,部署和管理很多的服务器,自然会想到该如何提高效率和有效的管理.在Windows Server 2008的时代微软已经提供称 ...

  7. 去掉windows8.1鸡肋的开始按钮

    无开始按钮了,win8.1的 开始按钮反而非常鸡肋.. 可以使用我分享的链接下载startisgone: http://download.csdn.net/detail/wangallan/89728 ...

  8. Android Studio failed to open by giving error “Files Locked” 解决方案

    windows 7 下的解决方案 导航至 android-studio 安装目录. (默认为C:\Program Files (x86)\Android\android-studio). 往上一层文件 ...

  9. WPF系列-CheckBox

    自定义样式1 效果: 代码: <!-- CheckBox的样式 --> <Style TargetType="{x:Type CheckBox}"> < ...

  10. 使用Vmware虚拟机部署开发环境之Mac OS X系统安装

    一.使用VMware虚拟机部署Swift开发环境所需工具: Vmware Workstation 10.0虚拟机软件 VM安装Mac解锁工具Unlock 苹果操作系统(Mac OS X Maveric ...