美文网首页.NET
[UWP]用画中画模式(CompactOverlay Mode)

[UWP]用画中画模式(CompactOverlay Mode)

作者: dino_chan | 来源:发表于2020-01-17 10:14 被阅读0次

1. 什么是,以及怎么用画中画

Windows 10 Creators Update以后UWP提供了一个新的视图模式CompactOverlay,中文翻译成 紧凑的覆盖层?反正大部分时间我们都会称它为画中画模式

image

上图中右上角即为进入画中画模式的微软“电影和电视”应用。

可以调用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 的窗口。

image

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

相关文章

  • [UWP]用画中画模式(CompactOverlay Mode)

    1. 什么是,以及怎么用画中画 Windows 10 Creators Update以后UWP提供了一个新的视图模...

  • vimtutor笔记

    几种模式 正常模式(Normal Mode) 插入模式(Insert Mode) 可视模式(Visual Mode...

  • android 8.0、9.0、10.0可用性分析

    一、 特性描述 android 8.0 特性 画中画模式Android 8.0 允许以画中画 (PIP) 模式启动...

  • vim 常用命令

    模式正常模式 (Normal-mode)插入模式 (Insert-mode)命令模式 (Command-mode)...

  • Vim-本猿必备

    3种模式 一般模式-common mode编辑模式-edit mode命令模式-command mode 基本操作...

  • 【linux编程】vim编辑器常用命令

    三种模式 command mode 命令模式 insert mode 输入模式 last line mode 底行...

  • VI命令汇总

    命令行模式command mode 插入模式(Insert mode) 底行模式

  • vim快速入门

    常用模式: 普通模式(Normal mode) 插入模式(Insert mode) 命令行模式(Command l...

  • Vim 编辑器常用命令

    (一)Vim模式 vim的三种工作模式:命令模式(Command Mode) 、输入模式(Input Mode)、...

  • VIM

    vim 基础 vim 有三种模式 命令模式(Command mode) ,插入模式(Insert mode), ...

网友评论

    本文标题:[UWP]用画中画模式(CompactOverlay Mode)

    本文链接:https://www.haomeiwen.com/subject/irlczctx.html