[UWP]用画中画模式(CompactOverlay Mode)让用总在最前端显示
Windows 10 Creators Update以后UWP提供了一个新的视图模式CompactOverlay,中文翻译成 紧凑的覆盖层?反正大部分时间我们都会称它为画中画模式。
上图中右上角即为进入画中画模式的微软“电影和电视”应用。
可以调用ApplicationView.TryEnterViewModeAsync函数进入或退出CompactOverlayer模式:
//进入CompactOverlay模式await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay);//返回默认模式await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.Default);
还可以使用ViewModePreferences
控制进入CompactOverlay时窗口的大小:
//进入CompactOverlay模式并将窗体设置为 200 x 200 像素var preferences = ViewModePreferences.CreateDefault(ApplicationViewMode.CompactOverlay);preferences.CustomSize = new Windows.Foundation.Size(200, 200);await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay, preferences);//返回默认模式var preferences = ViewModePreferences.CreateDefault(ApplicationViewMode.Default);await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.Default, preferences);
进入CompactOverlay模式后,窗体首先缩小并移动到屏幕右上方,并且有以下行为:
• 窗口置于顶层;• 最大化、最小化按钮消失;• 标题栏会在失去焦点并且鼠标离开后几秒钟消失;• 使用`Window.Current.SetTitleBar`设置为标题栏元素的内容也会在鼠标离开后消失;• 可以改变窗口大小,但只能在 150 x 150 到 500 x 500 之间改变;• 虽然标题栏消失,但左下右三个边框仍在;
因为尺寸有限制,所以超过 150 x 150 到 500 x 500 这个范围的ViewModePreferences.CustomSize不会生效,会取最接近范围的值。例如使用 700 x 500 会出现 500 x 500 的窗口。
2. 通过自定义StateTrigger响应画中画模式上一篇文章介绍过如何使用AdaptiveTrigger实现响应式布局,CompactOverlay的情况更加极端,毕竟有可能从1920 x 1050突然变成150 x 150。为了应对这种情况,我自定义了一个StateTrigger,根据ApplicationView.ViewMode的值判断是否激活当前的State。这个类继承自StateTriggerBase
,在监视的FrameworkElement的SizeChanged事件中调用SetActive
改变State的激活状态。具体代码及使用方式如下:
public class IsCompactOverlayModeTrigger : StateTriggerBase{ private FrameworkElement _targetElement; public FrameworkElement TargetElement { get { return _targetElement; } set { if (_targetElement != null) { _targetElement.SizeChanged -= OnSizeChanged; } _targetElement = value; _targetElement.SizeChanged += OnSizeChanged; } } private void OnSizeChanged(object sender, SizeChangedEventArgs e) { var view = ApplicationView.GetForCurrentView(); SetActive(view.ViewMode == ApplicationViewMode.CompactOverlay); }}
<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState> <VisualState.StateTriggers> <helpers:IsCompactOverlayModeTrigger TargetElement="{x:Bind}" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="CompactView.Opacity" Value="1" /> <Setter Target="CompactView.IsHitTestVisible" Value="True" /> <Setter Target="NormalView.Opacity" Value="0" /> <Setter Target="NormalView.IsHitTestVisible" Value="False" /> </VisualState.Setters> </VisualState> </VisualStateGroup></VisualStateManager.VisualStateGroups>
虽然前一篇文章介绍了使用Visibility改变视图,但使用了ImplicitAnimation的话改变Visibility会触发动画,所以有时我会使用Opacity和IsHitTestVisible来显示/隐藏UI元素。
3. 或者索性导航到新的页面使用 StateTrigger毕竟还是有些繁琐,大部分情况下需要用到画中画模式的应用,CompactOverlay的视图都是固定的那几个,所以可以直接导航到一个新页面。
private async void OnEnterDefault(object sender, RoutedEventArgs e){ var preferences = ViewModePreferences.CreateDefault(ApplicationViewMode.Default); await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.Default, preferences);}private async void OnEnterCompactOverlay(object sender, RoutedEventArgs e){ var preferences = ViewModePreferences.CreateDefault(ApplicationViewMode.CompactOverlay); preferences.CustomSize = new Windows.Foundation.Size(150, 150); await ApplicationView.GetForCurrentView().TryEnterViewModeAsync(ApplicationViewMode.CompactOverlay, preferences); Frame.Navigate(typeof(CompactPage), null, new SuppressNavigationTransitionInfo());}
这时候记得要使用SuppressNavigationTransitionInfo暂停导航的过渡动画,否则会很难看。
4. 结语CompactOverlay mode – aka Picture-in-Picture
上面这篇文章还给出了更多有用的代码:如何判断是否支持CompactOverlay及如何在多视图模式下使用。但我没有用到就不再赘述了,有兴趣可以参考这个文章。
画中画模式对我的番茄钟应用很重要。虽然我很喜欢在第二个屏幕上使用番茄钟,一来不占用我的工作区域,二来可以提醒别人我正在专注工作不要打扰,但对很多只有一个屏幕的用户来说画中画模式更加实用。关于画中画模式的更多信息可以参考下面给出的网站。
5. 参考ApplicationView Class (Windows.UI.ViewManagement) - Windows UWP applications Microsoft Docs
ApplicationViewMode Enum (Windows.UI.ViewManagement) - Windows UWP applications Microsoft Docs
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。