Longhorn, Windows applications navigation abilities.
After checking the web navigation abilities it’s the windows application turn. As part of dressing windows application as web application windows application got their own navigation abilities. Avalon enables you to create navigation applications. To create such application you can use Whidbey and open new “Longhorn navigation application” project:
namespace NavigationApplication2
{
/// <summary>
/// Interaction logic for Application.xaml
/// </summary>
public partial class MyApp : NavigationApplication
{
}
}
Working with the navigation system is strait forward. You need to declare a base window which serve as a container to Panels (usually FlowPanel) that holds the display data. The main page contains the navigation buttons and the code to operate them. Each navigation between FlowPanel save the page in dedicate object called Journal. This object holds the page history and optionally state for every one of them. The main page derived from NavigationWindow and defines the first panel to load by using the WindowNavigationContainer tag:
<NavigationWindow
xmlns="http://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
def:Class="NavigationApplication2.Window1"
def:CodeBehind="Window1.xaml.cs"
Text="NavigationApplication2" Visible="True"
Activated="OnActivated" Deactivated="OnDeactivated"
Loaded="OnWindowLoaded"
>
<!-- The namespace + class name in the codebehind file and the def:Class attribute in the root of this document, must stay identical. You can change them, but you must keep them in sync. -->
<NavigationWindow.Resources>
<Style def:Name="BackButton">
<Button/>
<Style.VisualTree>
<Image def:StyleID="img" />
</Style.VisualTree>
<!-- Note: this is currently using Images, in the future it should be done using vector shapes, not images -->
<Style.VisualTriggers>
<PropertyTrigger Property="IsEnabled" Value="false">
<Set PropertyPath="Image.Source" Value="Images/travelbackdisabled.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="IsEnabled" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelbacknormal.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="IsMouseOver" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelbackhot.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="Pressed" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelbackpressed.png" Target="img" />
</PropertyTrigger>
</Style.VisualTriggers>
</Style>
<Style def:Name="ForwardButton">
<Button/>
<Style.VisualTree>
<Image def:StyleID="img" />
</Style.VisualTree>
<Style.VisualTriggers>
<PropertyTrigger Property="IsEnabled" Value="false">
<Set PropertyPath="Image.Source" Value="Images/travelfwddisabled.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="IsEnabled" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelfwdnormal.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="IsMouseOver" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelfwdhot.png" Target="img" />
</PropertyTrigger>
<PropertyTrigger Property="Pressed" Value="true">
<Set PropertyPath="Image.Source" Value="Images/travelfwdpressed.png" Target="img" />
</PropertyTrigger>
</Style.VisualTriggers>
</Style>
<!-- Gradient used in NavBar Background when window is active -->
<LinearGradientBrush def:Name="ActiveGradient">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#FF4E4E4E"/>
<GradientStop Offset="0.1" Color="#FF646464"/>
<GradientStop Offset="0.2" Color="#FF767676"/>
<GradientStop Offset="0.3" Color="#FF8E8E8E"/>
<GradientStop Offset="0.4" Color="#FF9E9E9E"/>
<GradientStop Offset="0.5" Color="#FFA5A5A5"/>
<GradientStop Offset="0.6" Color="#FF9E9E9E"/>
<GradientStop Offset="0.7" Color="#FF8E8E8E"/>
<GradientStop Offset="0.8" Color="#FF767676"/>
<GradientStop Offset="0.9" Color="#FF646464"/>
<GradientStop Offset="1.0" Color="#FF4E4E4E"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<!-- Gradient used in NavBar Background when window is inactive -->
<LinearGradientBrush def:Name="InactiveGradient">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#FF9CA1A2"/>
<GradientStop Offset="0.1" Color="#FFA9ADAE"/>
<GradientStop Offset="0.2" Color="#FFB3B8B9"/>
<GradientStop Offset="0.3" Color="#FFBFC2C3"/>
<GradientStop Offset="0.4" Color="#FFC7CACB"/>
<GradientStop Offset="0.5" Color="#FFCBCECF"/>
<GradientStop Offset="0.6" Color="#FFC7CACB"/>
<GradientStop Offset="0.7" Color="#FFBFC2C3"/>
<GradientStop Offset="0.8" Color="#FFB3B8B9"/>
<GradientStop Offset="0.9" Color="#FFA9ADAE"/>
<GradientStop Offset="1.0" Color="#FF9CA1A2"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</NavigationWindow.Resources>
<!-- Workaround - shouldn't need hardcoded height. -->
<FlowPanel ID="navBar" DockPanel.Dock="Top" Width="100%" Height="54px" >
<Button ID="backButton" Visibility ="Visible" IsEnabled="True" Click="OnBackClicked" Style="{BackButton}"></Button>
<Button ID="forwardButton" Visibility ="Visible" IsEnabled="True" Click="OnForwardClicked" Style="{ForwardButton}"></Button>
</FlowPanel>
<WindowNavigationContainer ID="wNavContainer" SourceUri="Pane1.xaml" Navigated="OnNavigated" >
</WindowNavigationContainer>
</NavigationWindow>
The page content should be inside panel so you need to create panel for every “Page” that you want to display. For demonstration purpose I’m going to use FlowPanel. The Panel XAML holds the visualization declaration, I use button to navigate to other “windows” but there are dedicate hyperlink control for navigation purpose. The XAML code behind holds the code to navigate to another Panel. To cause navigation you should use Navigate method of WindowNavigation type. To use WindowNavigation I use Application.MainWindow to get a reference to the container window and to navigate to other panel :
XAML :
<FlowPanel
xmlns="http://schemas.microsoft.com/2003/xaml"
xmlns:def="Definition"
def:Class="NavigationApplication2.Pane1"
def:CodeBehind="Pane1.xaml.cs"
>
<!-- The namespace + class name in the code behind file and the def:Class attribute in the root of this document, must stay identical. You can change them, but you must keep them in sync. -->
<!--
<SimpleText>Hello World</SimpleText>
-->
<Text > Wellcome </Text>
<Button ID="a" Click="OnClick" ToolTip ="Press me, please!!!!">Go to 1</Button>
</FlowPanel>
Code behind:
namespace NavigationApplication2
{
/// <summary>
/// Interaction logic for Pane1.xaml
/// </summary>
public partial class Pane1 : FlowPanel
{
// To use PaneLoaded put Loaded="PaneLoaded" in root element of .xaml file.
// private void PaneLoaded(object sender, EventArgs e) {}
// Sample event handler:
// private void ButtonClick(object sender, ClickEventArgs e) {}
private void OnClick(object sender, ClickEventArgs e)
{
((NavigationWindow)Application.MainWindow).Navigate(new Uri("PaneNavigationWindow1.xaml", false, true));
}
}
}
Longhorn navigation application enables the end user to navigate easily between windows of your application (similar to web navigation). Navigation enhanced the user experience and its relatively easy to implement.