代表目前 App 的 title bar,利用
ApplicationView.GetForCurrentView().TitleBar
取得,屬於 Windows.UI.ViewManagement。ApplicationView 代表目前執行 App 視窗與關聯的狀態/行爲。Name | Access Type | Description |
---|---|---|
BackgroundColor / ForegroundColor | Read/write | Gets or sets the color of the title bar background / foreground. |
InactiveBackgroundColor / InactiveForegroundColor | Read/write | Gets or sets the color of the title bar background / foreground when it's inactive. |
ButtonBackgroundColor / ButtonForegroundColor | Read/write | Gets or sets the background / foreground color of the title bar buttons. |
ButtonInactiveBackgroundColor / ButtonInactiveForegroundColor | Read/write | Gets or sets the background / foreground color of a title bar button when it's inactive. |
ButtonHoverBackgroundColor / ButtonHoverForegroundColor | Read/write | Gets or sets the background / foreground color of a title bar button when the pointer is over it. |
ButtonPressedBackgroundColor / ButtonPressedForegroundColor | Read/write | Gets or sets the background / foreground color of a title bar button when it's pressed. |
通常會設定會讓 Inactive 類型的顔色一致,這樣看起來比較好看;如果有改了 Background 也要記得一致改掉 ButtonBackground 不然會掉一塊色。
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
if (UseStandardColors.IsChecked.Value)
{
// 要設定爲 null 才會還原是用 系統預設
titleBar.BackgroundColor = null;
titleBar.ForegroundColor = null;
titleBar.InactiveBackgroundColor = null;
titleBar.InactiveForegroundColor = null;
titleBar.ButtonBackgroundColor = null;
titleBar.ButtonHoverBackgroundColor = null;
titleBar.ButtonPressedBackgroundColor = null;
titleBar.ButtonInactiveBackgroundColor = null;
titleBar.ButtonForegroundColor = null;
titleBar.ButtonHoverForegroundColor = null;
titleBar.ButtonPressedForegroundColor = null;
titleBar.ButtonInactiveForegroundColor = null;
}
else
{
// Title bar colors. Alpha must be 255.
titleBar.BackgroundColor = new Color() { A = 255, R = 54, G = 60, B = 116 };
titleBar.ForegroundColor = new Color() { A = 255, R = 232, G = 211, B = 162 };
titleBar.InactiveBackgroundColor = new Color() { A = 255, R = 135, G = 141, B = 199 };
titleBar.InactiveForegroundColor = new Color() { A = 255, R = 232, G = 211, B = 162 };
}
}
*** 要注意設定顔色的時候, title bar 的 alpha 必須是 255 (FF);title bar 中 button 的 foreground 也必須是 255,衹有 button 的 background 才可以設定 alpha。 ***
上述介紹怎麽調整 Title Bar 的顔色,讓畫面設計上能夠更符合自己 App 的色系。如果說這樣的調整還不夠滿足,往下將説明怎麽自訂自己的 Title Bar。
代表目前視窗的 title bar。允許 app 在視窗裏自定義 title bar。CoreApplicationView 代表目前 App 執行的視窗與它的執行續,屬於 Windows.ApplicationModel.Core。
Type | Name | Description |
---|---|---|
Event | IsVisibleChanged | Occurs when the visibility of the title bar (indicated by the IsVisible property) changes. |
LayoutMetricsChanged | Occurs when the title bar needs to respond to size changes. The most common trigger for this event is when the app window moves to a screen that has a different DPI. Use this event to verify and update the positioning of UI elements that depend on the title bar's size. | |
Property | ExtendViewIntoTitleBar | read/write. Gets or sets a value that specifies whether this title bar should replace the default window title bar. |
Height | read-only. Gets or sets the height of the title bar. | |
IsVisible | read-only. Gets a value that specifies whether this title bar is visible. | |
SystemOverlayLeftInset | read-only. Gets the width of the system-reserved region of the upper-left corner of the app window. This region is reserved when the current language is a right-to-left language. | |
SystemOverlayRightInset | read-only. Gets the width of the system-reserved region of the upper-right corner of the app window. This region is reserved when the current language is a left-to-right language. |
上述以 LayoutMetricsChanged,IsVisibleChanged,ExtendViewIntoTitleBar 這三個最常使用,例如:
- ExtendViewIntoTitleBar:設定是否支援自訂的 title bar。設定之後搭配
Window.Current.SetTitleBar
更新 title bar 内容。 - IsVisibleChanged:適用於支援全屏幕時要關掉或開啓,設定 IsVisible 后所觸發。
- ayoutMetricsChanged:適用於當用戶在 Desktop 下拉動視窗大小時所觸發,可用來設定顯示或開關 title bar 的内容。
參考範例説明:
1. 建立一個自定義的 TitleBar 跟載入 content 的 XAML:
<Grid x:Name="rootGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<!-- row = 1 放内容的地方 -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="Yellow" Grid.Row="0" x:Name="TitleBar">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid Background="Red" x:Name="BackButtonGrid">
<Button x:Name="BackButton" />
</Grid>
<Grid Grid.Column="1" x:Name="MainTitleBar" Background="Transparent">
<TextBlock Text="My custom title bar" VerticalAlignment="Center" FontSize="12" FontFamily="Segoe UI" FontWeight="Normal" Margin="10,0"></TextBlock>
</Grid>
</Grid>
</Grid>
2. 爲自定義的 Title bar 注冊 CoreApplicationViewTitleBar 的事件,并且設定給 Window.Current.SetTitleBar:
private void CustomTitleBar_Loaded(object sender, RoutedEventArgs e)
{
// 注冊事件
coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.IsVisibleChanged -= TitleBar_IsVisibleChanged;
coreTitleBar.IsVisibleChanged += TitleBar_IsVisibleChanged;
coreTitleBar.LayoutMetricsChanged -= TitleBar_LayoutMetricsChanged;
coreTitleBar.LayoutMetricsChanged += TitleBar_LayoutMetricsChanged;
}
private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
// 更新自定義 TitleBar 的高度
if (TitleBar != null)
{
TitleBar.Height = sender.Height;
}
}
private void TitleBar_IsVisibleChanged(CoreApplicationViewTitleBar sender, object args)
{
// 設定自定義 TitleBar 是否要顯示
if (TitleBar != null)
{
TitleBar.Visibility = sender.IsVisible ? Visibility.Visible : Visibility.Collapsed;
}
}
public void SetContent(UIElement content)
{
rootGrid.Children.Add(content);
Grid.SetRow((FrameworkElement)content, 1);
coreTitleBar.ExtendViewIntoTitleBar = true;
Window.Current.SetTitleBar(TitleBar);
}
public void RemoveContent(UIElement content)
{
rootGrid.Children.Remove((FrameworkElement)content);
coreTitleBar.ExtendViewIntoTitleBar = false;
Window.Current.SetTitleBar(null);
}
3. 更換 App 的 TitleBar:
private void ChangeToCustomTitleBar()
{
if (customTitleBar== null)
{
customTitleBar = new CustomTitleBar();
}
if (UseExtenTitleBar.IsChecked.Value)
{
// 先將目前畫面的内容暫時存起來
cacheContent = this.Content;
this.Content = customTitleBar;
// 設定給 custom title bar 并更新現在 mainpage 的 content
customTitleBar.SetContent(cacheContent);
}
else
{
// 還原原本的 content 給 mainpage
this.Content = cacheContent;
// 移除 custom title bar 的 content
customTitleBar.RemoveContent(cacheContent);
cacheContent = null;
}
}
上面的範例裏面有一段是在更換 Content 的内容,爲甚麽需要這個樣子,藉由下圖來説明:
可看出 Window.Current.SetTitleBar 之後整個畫面會往上提,所以需要保留一塊放 Title 的高度才能顯示正確。
更要特別注意的是,不要把整個 control 設定給 SetTitleBar 會造成原本 Content 的部分無法使用。
上述以自訂 title bar 的範例,因爲是自定義的所以原本預設的 back 按鈕,這是需要自己控制的,可以參考<UWP - 處理 back-navigation event 機制>。
瞭解了 TitleBar 的自訂與調整后,接著說明一下觀念上面怎麽分別 ApplicationView 跟 CoreApplicationView 的差別。
代表應用程式 view 與相關的狀態或行爲。在 Windows 裏面可以同時有 4 個 window 呈現在屏幕中,它們同時顯示的寬度可變,不重疊,並且其頂部和底部邊緣觸控式螢幕幕的頂部和底部邊緣。連續的視窗之間可能存在非視窗區域。
而 ApplicationView 不等於 window,它代表的 App 本體顯示的 view。
重要的屬性與事件,可以看出一些功能都是針對整個 App 的顯示在做控制,如下:
Type | Name | Description |
---|---|---|
Event | Consolidated | Occurs when the window is removed from the list of recently used apps, or if the user executes a close gesture on it. |
Method | ExitFullScreenMode | Takes the app out of full-screen mode. |
GetApplicationViewIdForWindow | Gets the window ID that corresponds to a specific CoreWindow managed by the app. | |
GetForCurrentView | Gets the view state and behavior settings of the active application. | |
TryEnterFullScreenMode | Attempts to place the app in full-screen mode. | |
Properties | FullScreenSystemOverlayMode | Gets or sets a value that indicates how an app in full-screen mode responds to edge swipe actions. |
IsFullScreen | Gets a value that indicates whether the window touches both the left and right sides of the display. | |
Orientation | Gets the current orientation (landscape or portrait) of the window (app view) with respect to the display. | |
IsFullScreenMode | Gets a value that indicates whether the app is running in full-screen mode. | |
IsOnLockScreen | Gets whether the window (app view) is on the Windows lock screen. | |
IsScreenCaptureEnabled | Gets or sets whether screen capture is enabled for the window (app view). | |
Title | Gets or sets the displayed title of the window. | |
TitleBar | Gets the title bar of the app. |
代表 app window 與它的 thread。開啓 App 之後會有一個 default 的 window,所以當使用 CoreApplication.GetCurrentView 時就可以拿到目前被啓用的 window。
可以搭配 CoreApplication.CreateNewView 建立新的 window。
重要的屬性與事件,如下:
Type | Name | Description |
---|---|---|
Event | Activated | Occurs when the view is activated. |
HostedViewClosing | Indicates that the hosted view is closing. Provides an opportunity for hosted window scenarios to defer the tear down of the hosted view. | |
Property | CoreWindow | Read-only. Gets the app window associated with the current view. |
Dispatcher | Read-only. Gets the event message dispatcher associated with the current view. | |
IsComponent | Read-only. Gets whether the app was launched as a component that is embedded in another app by calling the LaunchAsync method. | |
IsHosted | Read-only. Gets the value that indicates whether this app view is hosted or not. | |
IsMain | Read-only. Gets a value that indicates whether this app view is the main app view or not. | |
TitleBar | Read-only. Gets the title bar associated with the current view. |
- ApplicationView 與 CoreApplicationView 的差別: CoreApplicationView 控制的是 window,而 ApplicationView 控制的整個 App 的 view,而 view 裏面包括了多個 window。
更多的説明可以參考<The differences between Window ApplicationView CoreApplicationView and relationship?>。
[範例程式]
/DotblogsSampleCode
[補充]
取得目前 App 當前啓動的視窗。 Window 本身不是一個 control,重要的屬性事件方法如下:
Type | Name | Description |
---|---|---|
Event | Activated | Occurs when the window has successfully been activated. |
Closed | Occurs when the window has closed. | |
SizeChanged | Occurs when the app window has first rendered or has changed its rendering size. | |
VisibilityChanged | Occurs when the value of the Visible property changes. | |
Methods | Activate | Attempts to activate the application window by bringing it to the foreground and setting the input focus to it. |
Close | Closes the application window. | |
Properties | Bounds | Read-only. Gets a Rect value containing the height and width of the application window in units of effective (view) pixels. |
Content | Read-write. Gets or sets the visual root of an application window. | |
CoreWindow | Read-only. Gets an internal core object for the application window. | |
Current | Read-only. Gets the currently activated window for an application. | |
Dispatcher | Read-only. Gets the CoreDispatcher object for the Window, which is generally the CoreDispatcher for the UI thread. | |
Visible | Read-only. Gets a value that reports whether the window is visible. |
Window.Content 代表目前 App 執行的主要畫面會在 OnLaunched 先設定好。搭配在 SizeChanged 或是 VisibilityChanged 注意畫面被調整大小或是最小化的事件。
{ThemeResource} markup extension 可以取得目前系統使用的相關資源,它與 {StaticResource} markup extension 最大的不同在於,ThemeResource 會在每次用戶調整系統主題時就會被更動,跟 StaticResource 是在 XAML 載入后就固定是不同的。我比較常使用的就是
SystemAccentColor
來更換 Title bar 的顔色。<Grid Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Height="50"
Background="{ThemeResource SystemAccentColor}" />
- 如果需要在 App 開啓時自訂 splash screen 可以參考<Display a splash screen for more time>。
以上是分享在調整 Title bar 的一些心得。我自己在開發上面比較少會用到 custom title bar ,主要原因是那邊用戶的 touch, mouse 要移動并不方便,加上在 Mobile 版本裏面是沒有支援的(衹有 StatusBar 可以簡單控制 UI)。不過在 Desktop 上可能還有很多使用情境是我沒有想到的。希望這篇對大家有幫助。謝謝。
References
- Windows.UI.ViewManagement
- Display a splash screen for more time
- Easily manage the Title Bar in Windows 10 apps
- [UWP]Take the control of your title bar
- XAML theme resources & {ThemeResource} markup extension
- ResourceDictionary and XAML resource references
- Exploring W10 APIs – Windows and TitleBar
- UWP Windows 10 App, TitleBar and Status bar customization
- UWP App Development: Styling the Desktop Title Bar
沒有留言:
張貼留言