您好,登錄后才能下訂單哦!
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 的窗口。
上一篇文章介紹過如何使用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元素。
使用 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暫停導航的過渡動畫,否則會很難看。
CompactOverlay mode – aka Picture-in-Picture
上面這篇文章還給出了更多有用的代碼:如何判斷是否支持CompactOverlay及如何在多視圖模式下使用。但我沒有用到就不再贅述了,有興趣可以參考這個文章。
畫中畫模式對我的番茄鐘應用很重要。雖然我很喜歡在第二個屏幕上使用番茄鐘,一來不占用我的工作區域,二來可以提醒別人我正在專注工作不要打擾,但對很多只有一個屏幕的用戶來說畫中畫模式更加實用。關于畫中畫模式的更多信息可以參考下面給出的網站。
ApplicationView Class (Windows.UI.ViewManagement) - Windows UWP applications Microsoft Docs
ApplicationViewMode Enum (Windows.UI.ViewManagement) - Windows UWP applications Microsoft Docs
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。