⬆️ ⬇️

UWP beginner: Window title in applications (VB.NET + C #)

With the release of Windows 10, Microsoft has returned the concept of a window in its original form for applications from the Windows Store. Now, using the usual buttons in the upper right corner, you can resize, minimize / maximize and close the window, regardless of the type of application. The most interesting thing is that Microsoft did not abandon its original direction - content orientation. This philosophy is not universal, but it is well suited for a variety of applications. Agree, if you make a game or reader, then the standard header with the colors set automatically can slightly spoil the design of the application. Therefore, the new wide possibilities of customizing the header in the applications of the universal Windows platform (UWP) have become an absolute advantage.



This material was prepared jointly with an active member of the Microsoft Developer community, Alexey Plotnikov , and Stas Pavlov , manager for working with technical audiences. In it, we’ll talk about possible header settings within a UWP application.







1. Hide the title. Just for those cases when the application requires full immersion in the content and the title is not needed, there is a function to hide the title and put the application in full-screen mode.

')

Make it extremely simple:



VB.NET



'    ApplicationView.GetForCurrentView.TryEnterFullScreenMode() '    ApplicationView.GetForCurrentView.ExitFullScreenMode() 


C #



 //    ApplicationView.GetForCurrentView().TryEnterFullScreenMode(); //    ApplicationView.GetForCurrentView().ExitFullScreenMode(); 


Please note that the TryEnterFullScreenMode function returns a Boolean value, which will ensure that the transition to full-screen mode, which is not always guaranteed, is successful.



This code is best used when you need to switch the application to full screen mode and back in response to user actions. If you want to launch the application in full screen mode, you need to place the following code at the beginning of the OnLaunched method of the application:



VB.NET



 ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen 


C #



 ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen; 


A nice addition to this approach is that the application will immediately start in full screen mode, including the splash screen, and will also remember this rule for subsequent launches.



Note: to unify the behavior of UWP applications and WinRT, when switching to full screen mode, you can see the title bar if you move the mouse cursor to the upper edge of the window. This will be useful when designing an application.



2. Tweaking. In fact, the ability to completely replace the standard title with your own one without having to worry about standard behavior, such as dragging a window over the title, first appeared. In essence, this means that now you can put everything that comes to your head in the place of the headline. This method allows you to replace only the part of the header that contains the icon and the name of the application. The part with the window control buttons can not be replaced with our own.



If you immerse yourself in this functionality, the word "replacement" does not quite fit. Rather, we ask the platform to hide the standard header and tell which element in XAML will perform its functions.



It is done in just two lines of code:



VB.NET



 '    (   ) Core.CoreApplication.GetCurrentView.TitleBar.ExtendViewIntoTitleBar = True '     . Window.Current.SetTitleBar(CustomTitleBar) 


WITH#



 //    (   ) CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; //     . Window.Current.SetTitleBar(CustomTitleBar); 


And this is where the fun begins. The specified element may not only be very different from the usual title, but also be located anywhere in the window. The second line of code will not put it in the right place and will not give the correct size, it will just notify the platform that, in the opinion of the developer, is the title. The only thing that will end up is the ability to drag a window by clicking on this element, without the need for additional actions in the code.



All this is extremely important to understand and remember that personalization should never go against the user's habits. Keeping this in mind, you need to take care that the heading is placed in place of the standard heading and has the appropriate height and color.



What it looks like in XAML:



  <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="32"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Background="LightBlue" x:Name="CustomTitleBur"> <TextBlock VerticalAlignment="Center" Margin="10,0,0,0"> </TextBlock> <Image Margin="20,4,0,4" Source="Assets/StoreLogo.png"></Image> </StackPanel> </Grid> 








In this example, you can see that the text of the header and the icon are swapped. Everything looks very simple and clear, but there are a number of important aspects.



First, if you tell the platform that you need to use your own title, it will give the previously unavailable part of the window under the layout, which means all the content will move up. Given this, you need to ensure that in the upper part of the layout there is only an element replacing the standard header, and also make sure that nothing is overlapped with the window control buttons. In XAML above the root Grid, one line under the header is 32 units high. There is another trick here - the height of the window control buttons depends on the Windows settings and is equal to 32 only with the standard settings, so a respected developer will take care of tracking the changes in settings and react to this. In the MSDN article on the Window.SetTitleBar method, you can learn more about how to do this.



Secondly, it is necessary to remember that the platform treats the element as a normal title, which means that placing the button there will be impossible to catch the events of its pressing. All mouse events will be captured by the platform and used to drag the window.



It may seem to you that you can bypass the previous restriction simply by removing the line of code:



VB.NET



 Window.Current.SetTitleBar(CustomTitleBar) 


C #



 Window.Current.SetTitleBar(CustomTitleBar); 


But, the platform will simply hide the standard header, and the required element will not be set as the title. Then you can simply determine the areas for which the window can be dragged and add the necessary actions in the code? But no, it's not that simple. In fact, if you do not call the SetTitleBar method, then everything that is in the window layout will fall into the place of the former header, lose the ability to catch input and behave like a header. Why, then, need this line of code? It is needed in order to accurately determine the places that behave like a heading. If you need to place a button there, then it must be outside the CustomTitleBar element.



Rewrite our XAML as follows:



  <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="32"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="FullScreenButton" Click="FullScreenButton_Click"> <FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}" Glyph=""/> </Button> <Grid Background="LightBlue" Grid.Column="1" x:Name="CustomTitleBar"> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" Margin="10,0,0,0"> </TextBlock> <Image Margin="20,4,0,4" Source="Assets/StoreLogo.png"></Image> </StackPanel> </Grid> </Grid> </Grid> 


And in the window code the following will be written:



VB.NET



  Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs) Core.CoreApplication.GetCurrentView.TitleBar.ExtendViewIntoTitleBar = True Window.Current.SetTitleBar(CustomTitleBur) AddHandler Window.Current.SizeChanged, AddressOf CurrentWindow_SizeChanged End Sub Private Sub CurrentWindow_SizeChanged(sender As Object, e As WindowSizeChangedEventArgs) Dim view = ApplicationView.GetForCurrentView If Not view.IsFullScreenMode Then view.ExitFullScreenMode() CustomTitleBur.Visibility = Visibility.Visible FullScreenButton.Visibility = Visibility.Visible End If End Sub Private Sub FullScreenButton_Click(sender As Object, e As RoutedEventArgs) Dim view = ApplicationView.GetForCurrentView If view.TryEnterFullScreenMode() Then CustomTitleBur.Visibility = Visibility.Collapsed FullScreenButton.Visibility = Visibility.Collapsed End If End Sub 


C #



  public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; } private void MainPage_Loaded(object sender, RoutedEventArgs e) { Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true; Window.Current.SetTitleBar(CustomTitleBar); Window.Current.SizeChanged += Current_SizeChanged; FullScreenButton.Click += FullScreenButton_Click; } private void FullScreenButton_Click(object sender, RoutedEventArgs e) { var view = ApplicationView.GetForCurrentView(); if (!view.TryEnterFullScreenMode()) { CustomTitleBar.Visibility = Visibility.Visible; FullScreenButton.Visibility = Visibility.Collapsed; } } private void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e) { var view = ApplicationView.GetForCurrentView(); if (!view.IsFullScreenMode) { view.ExitFullScreenMode(); CustomTitleBar.Visibility = Visibility.Visible; FullScreenButton.Visibility = Visibility.Visible; } } 


As an example, put the maximize button in the header in the full-screen mode. Despite the fact that there is not much sense in such a button, which will become clear below, this example is quite suitable for mastering the subtleties of working with a title.



So, consider an example in more detail. To begin with, in order to be able to invoke a button click event, you need to bring it outside the CustomTitleBar element. CustomTitleBar itself is wrapped in a shaded Grid, since without a fill it cannot catch mouse input, and it will be impossible to drag a window over the entire title. In addition to the previously described lines that hide the standard header and set the required one, a subscription to the window resizing event is added to the window loading events.



Now, at that moment, when we translate the window into full-screen mode, the title does not disappear anywhere. CustomTitleBar remains in its place, but it loses the function of the title. When you hover the mouse cursor over the top of the screen, window control buttons appear on top, which allow you to return to normal mode. If to switch to full screen mode and hide your title, it is enough to respond to the button event, then in order to know that the window has returned to normal mode, you will have to subscribe to the window resizing event.



Experimenting with this code, you can achieve many interesting results, but do not forget about standardization and convenience. For example, you can place CustomTitleBar at the bottom of the window and then you will be able to drag the window not at the top, but at the bottom, but the user is unlikely to say “thank you” for that. Think about the need for a solution before applying it. By the way, a very good example of implementing your own header is the Microsoft Edge browser, in which tabs are part of the header.







3. Change the color of the title. The method described above is extremely interesting and quite flexible, but in most scenarios it will be unnecessary to create its own element and complicate the life with its correct setting. It is much easier to simply repaint the elements of the system header in the colors of the application. The set of parameters responsible for the header colors is wide enough to achieve harmony with the rest of the application.



To shorten the code, you can get a link to the current TitleBar and then work with it:



VB.NET



 Dim tb As ApplicationViewTitleBar = ApplicationView.GetForCurrentView.TitleBar 


C #



 ApplicationViewTitleBar tb = ApplicationView.GetForCurrentView().TitleBar; 


Consider all the properties that are responsible for the colors of the header elements:



VB.NET



 '  ,        . tb.BackgroundColor = Windows.UI.Colors.LightBlue '      tb.ButtonBackgroundColor = Windows.UI.Colors.LightBlue '       (, , ). tb.ButtonForegroundColor = Windows.UI.Colors.Black '           . !      . tb.ButtonHoverBackgroundColor = Windows.UI.Colors.Blue '            . !      . tb.ButtonHoverForegroundColor = Windows.UI.Colors.White '       ,     tb.ButtonInactiveBackgroundColor = Windows.UI.Colors.Gray '        ,     tb.ButtonInactiveForegroundColor = Windows.UI.Colors.White '          . !      . tb.ButtonPressedBackgroundColor = Windows.UI.Colors.DarkBlue '           . !      . tb.ButtonPressedForegroundColor = Windows.UI.Colors.White '     tb.ForegroundColor = Windows.UI.Colors.Black '    ,     tb.InactiveBackgroundColor = Windows.UI.Colors.Gray '      ,     tb.InactiveForegroundColor = Windows.UI.Colors.White 


C #



 //  ,        . tb.BackgroundColor = Windows.UI.Colors.LightBlue; //      tb.ButtonBackgroundColor = Windows.UI.Colors.LightBlue; //       (, , ). tb.ButtonForegroundColor = Windows.UI.Colors.Black; //           . !      . tb.ButtonHoverBackgroundColor = Windows.UI.Colors.Blue; //            . !      . tb.ButtonHoverForegroundColor = Windows.UI.Colors.White; //       ,     tb.ButtonInactiveBackgroundColor = Windows.UI.Colors.Gray; //        ,     tb.ButtonInactiveForegroundColor = Windows.UI.Colors.White; //          . !      . tb.ButtonPressedBackgroundColor = Windows.UI.Colors.DarkBlue; //           . !      . tb.ButtonPressedForegroundColor = Windows.UI.Colors.White; //     tb.ForegroundColor = Windows.UI.Colors.Black; //    ,     tb.InactiveBackgroundColor = Windows.UI.Colors.Gray; //      ,     tb.InactiveForegroundColor = Windows.UI.Colors.White; 


By experimenting with each of these properties, you can achieve a harmonious design and your application will successfully respond to the content orientation philosophy.



It is also possible to use the properties responsible for the colors of the buttons to adapt them to your personal header, which you can create using the method described above.







It is worth noting that the settings that are responsible for the colors of the window control buttons are also responsible for the “Back” button, which appeared in UWP applications and is located in the window header (we are going to write a separate material about it).



This is the end of the description for setting the header in UWP applications. It is worth noting that all of the above is important for applications running on the desktop. If the application runs in tablet mode or on a mobile device, there is no title in it.



The second article from the UWP beginner series: Adaptive design .

Source: https://habr.com/ru/post/310326/



All Articles