📜 ⬆️ ⬇️

WPF - using page navigation, adding controls to NavigationWindow

In WPF, it is possible to create applications with the ability to navigate, that is, using Navigation objects, such as Page , NavigationService and NavigationWindow . Most of the examples on MSDN display how to use such objects in XBAP applications, but nobody forbids us to create client applications using page navigation.
So, we will try to create such an application. We create a new WPF Application project, from there we delete the created Window1.xaml, add two pages FirstPage.xaml and SecondPage.xaml, and also write the page with which our application will start in App.xaml:
StartupUri = "FirstPage.xaml" After starting, we should see a window of our application containing a navigation bar with forward and backward navigation buttons. Next, we need to create links that would help to move from one page to another. This can be done in different ways. Add a UserControl to the project and name it ApplicationToolbar. The first opportunity with which we can navigate between pages is to use the NavigationService , create a method for handling button presses with the following code: private void
{
NavigationService service = NavigationService.GetNavigationService (this);
service.Navigate (new Uri (e.Parameter.ToString (), UriKind.Relative));
} The method navigates to the page specified in the command parameters. In the xaml file of the ApplicationToolbar control, we will create a command, bind this method to it and point the buttons to the command to be executed:
< UserControl x:Class ="WPF_NavigationWindow.ApplicationToolbar" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" Height ="Auto" Width ="Auto" >
< UserControl.Resources >
<!-- -->
< RoutedCommand x:Key ="NavigationCommand" />
</ UserControl.Resources >
< UserControl.CommandBindings >
<!-- -->
< CommandBinding Command ="{StaticResource NavigationCommand}" Executed ="NavigationCommand_Executed" />
</ UserControl.CommandBindings >
< ToolBar HorizontalAlignment ="Right" >
<!-- -->
< Button CommandParameter ="FirstPage.xaml" Command ="{StaticResource NavigationCommand}" > First Page </ Button >
< Button CommandParameter ="SecondPage.xaml" Command ="{StaticResource NavigationCommand}" > Second Page </ Button >
</ ToolBar >
</ UserControl >


* This source code was highlighted with Source Code Highlighter .
Thus, we have created a panel with buttons for navigating between pages. You can use a simpler solution - Hyperlink , let's add it to our control:
< ToolBarPanel >
< TextBlock >
< Hyperlink NavigateUri ="FirstPage.xaml" > First Page </ Hyperlink >
< Hyperlink NavigateUri ="SecondPage.xaml" > Second Page </ Hyperlink >
</ TextBlock >
</ ToolBarPanel >


* This source code was highlighted with Source Code Highlighter .
So, as a result, we should get, approximately, the following view of the window:
Untitled
This is where the next desire arises: put our ApplicationToolbar control on the NavigationWindow (where the navigation buttons are located). The ability to override styles in WPF will help us do this. Namely style redefinition for NavigationWindow .
In order to describe the new style for NavigationWindow , or rather to rewrite the existing one, we initially need to pull out the style from the PresentationFramework libraries. In general, PresentationFramework has several sets of themes, such as Classic, Aero, Royale and Luna, each topic is in a separate library. I will look at the PresentationFramework.Aero library with its theme. In order to view the BAML file (after compilation, the xaml file is packaged in baml - Binary Application Markup) you can use the Reflector program with the BamlViewer plugin, but as practice has shown - BamlViewer does not do a good job with decompiling: it does not correctly spell the key names (Key) , does not correctly decode the data of the Geometry , even has a description of the triggers in front of the description of the content of the style - because of which the elements in the triggers are not located. In general, the StyleExplorer handles the BAML decompile task better . Here is a small screenshot of the comparison of these programs:
Untitled2
The most interesting thing is that the meaning of the keys of the styles is indeed as they appear in the screenshot - x: Key = "". That is, in our styles we can refer to the style with the name of the key Ì (if the style is connected). Why such strange key names are made is not clear (and it’s also clear that the BAML Viewer doesn’t recognize them correctly). As a result, Style Explorer provides us with a really working XAML text - for example, we can transfer all XAML text to our project and it will be valid, which cannot be said about BAML Viewer. But we don't need the whole XAML. We are interested in rewriting the NavigationWindow view, for this we initially create a new resource file Themes / General.xaml in our project (the file name and directory can be selected by anyone). In order for our resource file to be available in the application, we must also connect it in the App.xaml file, this is done like this:
< Application x:Class ="WPF_NavigationWindow.App" xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri ="FirstPage.xaml" >
< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
<!-- -->
< ResourceDictionary Source ="Themes/General.xaml" />
</ ResourceDictionary.MergedDictionaries >
</ ResourceDictionary >
</ Application.Resources >
</ Application >


* This source code was highlighted with Source Code Highlighter .
In the General.xaml file, we also need to include the resource file from the PresentationFramework.Aero library so that we can use the existing styles from the Aero theme in the style of our future NavigationManager. This is done in the same way:
< ResourceDictionary.MergedDictionaries >
< ResourceDictionary Source ="/PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component/themes/Aero.NormalColor.xaml" />
</ ResourceDictionary.MergedDictionaries >


* This source code was highlighted with Source Code Highlighter .
Next, from the Style Explorer, copy the style for NavigationWindow, as well as its ContentTemplate (which is used in the style). We will slightly change the ContentTemplate, or rather add our ApplicationToolbar control to it, we will not do anything else. Note that links to the resources of the form ì, ď, ê remain and they will work. As a result, we should have, approximately, such a set of styles (most of them commented out, everything remains what the Style Explorer gave us):
< ControlTemplate x:Key ="ď" TargetType ="{x:Type NavigationWindow}" >
< Border Background ="{TemplateBinding Control.Background}" BorderBrush ="{TemplateBinding Control.BorderBrush}" BorderThickness ="{TemplateBinding Control.BorderThickness}" >
< DockPanel >
< Grid Name ="NavChrome" Background ="{StaticResource ê}" DockPanel . Dock ="Top" Height ="30" >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="29" />
< ColumnDefinition Width ="26" />
< ColumnDefinition Width ="17" />
< ColumnDefinition Width ="*" />
</ Grid.ColumnDefinitions >
<!-- ... -->

<!-- -->
< WPF_NavigationWindow:ApplicationToolbar Grid . Row ="0" Grid . Column ="3" HorizontalAlignment ="Right" />
</ Grid >

<!-- ... -->
</ DockPanel >
</ Border >
< ControlTemplate.Triggers >
<!-- ... -->
</ ControlTemplate.Triggers >
</ ControlTemplate >

< Style x:Key ="{x:Type NavigationWindow}" TargetType ="{x:Type NavigationWindow}" >
<!-- ... -->
</ Style >


* This source code was highlighted with Source Code Highlighter .
As a result, our application will look like this:
Untitled3 As you can see, we have achieved that our ApplicationToolbar control is now located on the navigation bar.

Application Source Code: WPF_NavigationWindow.zip (12.64 KB)

')

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


All Articles