This content is not available in your language. Here's one version in another language that is currently available.
Request TranslationFrame
The Frame control from WPF supports content navigation within content. Frame can be hosted by a root element like Window, NavigationWindow, Page, UserControl, FlowDocument, or as an island within a content tree that belongs to a root element.
Using our extended Frame control, you can navigate with Fluent animations, better performance and more.
-
Inheritance: Object → (...) → Control → ContentControl → Frame → Frame
Examples
Navigate through pages
The following example shows how to create a simple Frame control to navigate through a set of pages.
First, create two pages called Page1.xaml
and Page2.xaml
. Create a folder named Pages
, right click the folder, and select Add → New Item. Select WPF / Page and name it Page1.xaml
. Repeat the process to create Page2.xaml
.
Add the namespace declaration to the root:
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
Change the root class from Page to ui:Page
. Go to the code-behind (e.g. Page1.xaml.cs), and change the base class from Page to iNKORE.UI.WPF.Modern.Controls.Page
.
Then add some content to the pages. For example, add a TextBlock
to each page to display the page name.
Your Page1 should look like this:
<ui:Page x:Class="WpfApp1.Pages.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
mc:Ignorable="d"
d:DesignHeight="360" d:DesignWidth="640"
Foreground="CornflowerBlue"
Title="Page 1">
<Grid>
<Rectangle Margin="10" Stroke="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ui:Page}, Path=Foreground}" StrokeThickness="2"
RadiusX="8" RadiusY="8" StrokeDashArray="4 2"/>
<TextBlock Text="Page 1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
</Grid>
</ui:Page>
using iNKORE.UI.WPF.Modern.Controls;
using Page = iNKORE.UI.WPF.Modern.Controls.Page;
namespace WpfApp1.Pages
{
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
}
}
And your Page2 should look like this:
<ui:Page x:Class="ExamplePhotoTaker.Pages.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ExamplePhotoTaker.Pages"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
mc:Ignorable="d"
d:DesignHeight="360" d:DesignWidth="640"
Foreground="SeaGreen"
Title="Page 2">
<Grid>
<Rectangle Margin="10" Stroke="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ui:Page}, Path=Foreground}" StrokeThickness="2"
RadiusX="8" RadiusY="8" StrokeDashArray="4 2"/>
<TextBlock Text="Page 2" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
</Grid>
</ui:Page>
using iNKORE.UI.WPF.Modern.Controls;
using Page = iNKORE.UI.WPF.Modern.Controls.Page;
namespace WpfApp1.Pages
{
public partial class Page2 : Page
{
public Page2()
{
InitializeComponent();
}
}
}
Now, create a new window and add a Frame control to it. Add a few buttons to navigate between the pages. Use the Navigate() method to pass Page to the Frame control.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center">
<Button x:Name="Button_NavigateToPage1" Content="To Page 1" Click="Button_NavigateToPage1_Click"/>
<Button x:Name="Button_NavigateToPage2" Content="To Page 2" Click="Button_NavigateToPage2_Click"/>
</ui:SimpleStackPanel>
<ui:Frame x:Name="Frame_Main" Margin="10" Grid.Row="1"
BorderBrush="Gray" BorderThickness="2,2,2,2"/>
</Grid>
Page1 Page_1 = new Page1();
Page2 Page_2 = new Page2();
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(Page_1);
}
private void Button_NavigateToPage2_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(Page_2);
}
Clicking the buttons will navigate to the corresponding pages like this:
We strongly NOT recommend you to use the Navigate(Type sourcePageType)
method to navigate between pages, it's not recommended to use it in the modern UI development. Instead, we recommend you to use the Navigate(object content)
method which we provided in the Frame control.
For example, we may change the code from this:
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(typeof(Page1));
}
to this:
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(new Page1());
}
or this, which is even better:
Page1 Page_1 = new Page1();
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(Page1);
}
Change transition style
On the Navigate() method, there are a few overloads that allow you to pass a transition style. The following example shows how to apply the Drill-in transition style.
using iNKORE.UI.WPF.Modern.Media.Animation;
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
Frame_Main.Navigate(Page_1, new DrillInNavigationTransitionInfo());
}
Disable keyboard navigation
Since the Frame has a built-in keyboard navigation, you may found out that you can use Backspace
, Page Down
and Page Up
keys to navigate through the pages without your code control. Mostly this is not expected since the user would misact and back to another page that you're not expected, so we recommend you use the following way to disable it.
First add a handler to the Navigating
event of the Frame control:
<ui:Frame x:Name="Frame_Main" Navigating="Frame_Main_Navigating"/>
Create your own Navigate method and block the navigation if it's not expected like this:
WeakReference __Frame_Main_NavigatingTarget = new WeakReference(null);
private void Frame_Main_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (e.Content != __Frame_Main_NavigatingTarget.Target)
{
e.Cancel = true;
}
}
public void NavigateTo(object content, object? extraData = null, NavigationTransitionInfo? infoOverride = null)
{
__Frame_Main_NavigatingTarget.Target = content;
Frame_Main.Navigate(content, extraData, infoOverride);
}
Then change your navigation code to use the new NavigateTo() method:
private void Button_NavigateToPage1_Click(object sender, RoutedEventArgs e)
{
// Don't use `Frame_Main.Navigate(Page_1) any more, it won't work.`
NavigateTo(Page_1);
}
private void Button_NavigateToPage2_Click(object sender, RoutedEventArgs e)
{
NavigateTo(Page_2);
}
Then try to use the keyboard to navigate through the pages, you'll find out that it's not working any more.
Members
Here're the commonly used members of the Frame control. For a complete list of members, please check the API definition.
Navigate
The Navigate() method navigates to the specified content. There are a few overloads that allow you to pass a transition style.
These are the extra overloads which we added for the Frame control:
/// <summary>
/// Causes the Frame to load content represented by the specified Page.
/// </summary>
/// <param name="sourcePageType">The page to navigate to, specified as a type reference to its partial class type.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(Type sourcePageType);
/// <summary>
/// Causes the Frame to load content represented by the specified Page, also passing
/// a parameter to be interpreted by the target of the navigation.
/// </summary>
/// <param name="sourcePageType">The page to navigate to, specified as a type reference to its partial class type.</param>
/// <param name="parameter">The navigation parameter to pass to the target page.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(Type sourcePageType, object parameter);
/// <summary>
/// Causes the Frame to load content represented by the specified Page -derived data
/// type, also passing a parameter to be interpreted by the target of the navigation,
/// and a value indicating the animated transition to use.
/// </summary>
/// <param name="sourcePageType">The page to navigate to, specified as a type reference to its partial class type.</param>
/// <param name="parameter">The navigation parameter to pass to the target page.</param>
/// <param name="infoOverride">Info about the animated transition.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(Type sourcePageType, object parameter, NavigationTransitionInfo infoOverride);
/// <summary>
/// Navigates asynchronously to content that is contained by an object.
/// </summary>
/// <param name="content">An System.Object that contains the content to navigate to.</param>
/// <param name="infoOverride">Info about the animated transition.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(object content, NavigationTransitionInfo infoOverride);
/// <summary>
/// Navigates asynchronously to content that is contained by an object, and passes
/// an object that contains data to be used for processing during navigation.
/// </summary>
/// <param name="content">An System.Object that contains the content to navigate to.</param>
/// <param name="extraData">A System.Object that contains data to be used for processing during navigation.</param>
/// <param name="infoOverride">Info about the animated transition.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(object content, object extraData, NavigationTransitionInfo infoOverride);
/// <summary>
/// Navigates asynchronously to source content located at a uniform resource identifier
/// (URI), and passes an object that contains data to be used for processing during
/// navigation, and a value indicating the animated transition to use.
/// </summary>
/// <param name="source">A System.Uri object initialized with the URI for the desired content.</param>
/// <param name="extraData">A System.Object that contains data to be used for processing during navigation.</param>
/// <param name="infoOverride">Info about the animated transition.</param>
/// <returns>true if navigation is not canceled; otherwise, false.</returns>
public bool Navigate(Uri source, object extraData, NavigationTransitionInfo infoOverride);
There're also many overloads presented in the original Frame.Navigate method, click here to learn more.
GoBack
The GoBack() method navigates to the most recent item in back navigation history, if a Frame manages its own navigation history.
/// <summary>
/// Navigates to the most recent item in back navigation history, if a Frame manages
/// its own navigation history, and specifies the animated transition to use.
/// </summary>
/// <param name="transitionInfoOverride">Info about the animated transition to use.</param>
public void GoBack(NavigationTransitionInfo transitionInfoOverride);
You can call the GoBack method with or without the transition info like this:
// Without transitionInfoOverride, default transition will be used.
Frame_Main.GoBack();
or this:
// With transitionInfoOverride, specified transition will be used.
Frame_Main.GoBack(new DrillInNavigationTransitionInfo());
Remarks
Transitions
Page transitions provide visual feedback about the relationship between pages.
Entrance
Page refresh is a combination of a slide up animation and a fade in animation for the incoming content. Use page refresh when the user is taken to the top of a navigational stack, such as navigating between tabs or left-nav items.
The desired feeling is that the user has started over.
The page refresh animation is represented by the EntranceNavigationTransitionInfo class.
// Explicitly play the page refresh animation
myFrame.Navigate(Page_2, null, new EntranceNavigationTransitionInfo());
A Frame automatically uses NavigationThemeTransition to animate navigation between two pages. By default, the animation is page refresh.
Drill
Use drill when users navigate deeper into an app, such as displaying more information after selecting an item.
The desired feeling is that the user has gone deeper into the app.
The drill animation is represented by the DrillInNavigationTransitionInfo class.
// Play the drill in animation
myFrame.Navigate(Page_2, null, new DrillInNavigationTransitionInfo());
Slide
Use slide transition to show that sibling pages appear next to each other. The NavigationView control automatically uses this animation for top nav, but if you are building your own horizontal navigation experience, then you can implement horizontal slide with SlideNavigationTransitionInfo.
The desired feeling is that the user is navigating between pages that are next to each other.
// Navigate to the right, ie. from LeftPage to RightPage
myFrame.Navigate(RightPage, null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
// Navigate to the left, ie. from RightPage to LeftPage
myFrame.Navigate(LeftPage, null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromLeft });
// Navigate to the bottom, ie. from TopPage to BottomPage
myFrame.Navigate(BottomPage, null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromBottom });
Suppress
To avoid playing any animation during navigation, use SuppressNavigationTransitionInfo in the place of other NavigationTransitionInfo subtypes.
// Suppress the default animation
myFrame.Navigate(Page2, null, new SuppressNavigationTransitionInfo());
Suppressing the animation is useful when implicit show/hide animations is used.