1. 什麼是,以及怎麼用畫中畫 Windows 10 Creators Update以後UWP提供了一個新的視圖模式CompactOverlay,中文翻譯成 緊湊的覆蓋層 ?反正大部分時間我們都會稱它為 畫中畫模式 。 上圖中右上角即為進入畫中畫模式的微軟“電影和電視”應用。 可以調用 "Appli ...
1. 什麼是,以及怎麼用畫中畫
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