.NET MAUI Page Types: TabbedPage and FlyoutPage
Microsoft .NET Multi-platform App UI (MAUI) provides developers with a robust framework for building cross-platform applications. Within this framework, .NET MAUI introduces a variety of page types, each designed to offer unique functionalities and user experiences. Two essential and versatile page types in .NET MAUI are TabbedPage
and FlyoutPage
. This article will detail these page types, highlighting their importance, features, and usage.
TabbedPage
TabbedPage
is a container that displays multiple pages within a single UI, organized by tabs along the bottom or top of the screen. Each tab corresponds to a separate page, allowing users to easily switch between different sections of an application.
Key Features:
Tab Organization: Users can navigate between multiple pages using tabs, making it ideal for applications with multiple sections or categories.
Customizable Tabs: Developers can customize the appearance and behavior of tabs, including setting icons and labels.
Built-in Navigation: Provides built-in navigation capabilities through tab selection.
Usage Scenarios:
- Shopping Application: Different tabs for categories like Men's, Women's, Electronics, etc.
- News Application: Tabs for different news sections like Entertainment, Sports, Politics, etc.
- Personal Finance Application: Tabs for Income, Expenses, Budgeting, etc.
Example Code:
public class HomePage : TabbedPage
{
public HomePage()
{
Children.Add(new NavigationPage(new MenPage()) { Title = "Men", IconImageSource = "men.png" });
Children.Add(new NavigationPage(new WomenPage()) { Title = "Women", IconImageSource = "women.png" });
Children.Add(new NavigationPage(new KidsPage()) { Title = "Kids", IconImageSource = "kids.png" });
}
}
Importance:
TabbedPage
is crucial for applications that need to present a variety of content in a simple, organized manner. It simplifies navigation and enhances the user experience by providing quick access to different sections of the app.
FlyoutPage
FlyoutPage
is a container that displays two pages: a flyout menu and a detail page. The flyout menu typically contains navigation options, while the detail page displays the content based on the selected menu item.
Key Features:
Hamburger Menu: The flyout menu can be toggled via a hamburger menu, ideal for applications with limited screen space.
Customizable UI: Supports customization of the flyout menu and detail page, enabling a flexible design.
Responsive Navigation: Suitable for various screen sizes and orientations.
Usage Scenarios:
- Content Management Systems (CMS): For managing different types of content within a single application.
- Administrative Applications: For managing user settings, permissions, and data.
- Multi-tenant Applications: For switching between different tenants or user roles.
Example Code:
public class HomePage : FlyoutPage
{
public HomePage()
{
Flyout = new MenuPage();
Detail = new NavigationPage(new HomePageContent());
}
}
Inside MenuPage
(Flyout):
public class MenuPage : ContentPage
{
public MenuPage()
{
var listView = new ListView
{
ItemsSource = new List<MenuPageItem>()
{
new MenuPageItem() { Title = "Home", TargetType = typeof(HomePageContent) },
new MenuPageItem() { Title = "Settings", TargetType = typeof(SettingsPage) },
new MenuPageItem() { Title = "Profile", TargetType = typeof(ProfilePage) }
},
ItemTemplate = new DataTemplate(() =>
{
var label = new Label();
label.SetBinding(Label.TextProperty, "Title");
return new ViewCell { View = label };
})
};
listView.ItemSelected += ListView_ItemSelected;
Content = new StackLayout
{
Children = { listView }
};
}
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (MenuPageItem)e.SelectedItem;
var page = (Page)Activator.CreateInstance(item.TargetType);
var currentPage = ((FlyoutPage)Parent.Parent).Detail as NavigationPage;
currentPage.PushAsync(page);
((ListView)sender).SelectedItem = null;
}
}
class MenuPageItem
{
public string Title { get; set; }
public Type TargetType { get; set; }
}
Importance:
FlyoutPage
is vital for applications that need a more structured, hierarchical navigation system. It's particularly useful in scenarios where a compact, collapsible menu is required, making it ideal for applications with extensive navigation options.
Conclusion
Both TabbedPage
and FlyoutPage
are integral components of the .NET MAUI framework, offering developers powerful tools to create intuitive, user-friendly applications. TabbedPage
is ideal for applications with multiple, distinct sections, while FlyoutPage
is perfect for those needing a structured, hierarchical navigation system. By leveraging these page types, developers can significantly enhance the user experience and functionality of their cross-platform apps.
Step-by-Step Guide: Working with .NET MAUI Page Types - TabbedPage and FlyoutPage
.NET Multi-platform App UI (.NET MAUI) allows you to create rich, natively built multi-platform applications using C# and XAML. Two of the most commonly used page types in .NET MAUI are TabbedPage
and FlyoutPage
. These page types provide a straightforward way to organize and switch between different views within your application.
In this guide, we will cover how to set up a route and run your application, then walk through the data flow process step-by-step for beginners. We'll focus on using both TabbedPage
and FlyoutPage
.
Prerequisites
- Visual Studio 2022 or later with .NET MAUI workload installed.
- Basic knowledge of C# and XAML.
Setting Up Your Project
Let's begin by creating a new .NET MAUI project.
- Open Visual Studio and create a new project.
- Choose .NET MAUI App from the templates.
- Fill out the project details, ensuring that you have selected the appropriate target platforms (iOS, Android, macOS, Windows).
- Click Create to create a new .NET MAUI project.
Step 1: Implementing TabbedPage
TabbedPage
is a composite page that displays multiple tabs that users can switch between. Each tab is a separate page.
XAML Code for TabbedPage
Open your App.xaml
and modify it to use TabbedPage
as the main page.
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:YourNamespace"
x:Class="YourNamespace.App">
<Application.MainPage>
<TabbedPage>
<TabbedPage.Children>
<local:HomePage Title="Home" />
<local:SettingsPage Title="Settings" />
</TabbedPage.Children>
</TabbedPage>
</Application.MainPage>
</Application>
Create HomePage and SettingsPage
Create two separate pages, HomePage.xaml
and SettingsPage.xaml
, each containing simple content.
<!--HomePage.xaml-->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourNamespace.HomePage"
Title="Home">
<StackLayout>
<Label Text="Welcome to the Home Page!"
HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
<!--SettingsPage.xaml-->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourNamespace.SettingsPage"
Title="Settings">
<StackLayout>
<Label Text="This is the Settings Page!"
HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
Code-Behind (Optional)
You can also create the TabbedPage
in C#.
using Microsoft.Maui.Controls;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new TabbedPage
{
Children =
{
new HomePage(),
new SettingsPage()
}
};
}
}
Step 2: Implementing FlyoutPage
FlyoutPage
is a composite page that displays a flyout menu and a detail page. The flyout menu typically contains navigation items, and the detail page displays the selected content.
XAML Code for FlyoutPage
Open your App.xaml
and modify it to use FlyoutPage
as the main page.
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:YourNamespace"
x:Class="YourNamespace.App">
<Application.MainPage>
<FlyoutPage>
<FlyoutPage.Flyout>
<local:FlyoutMenuPage />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<local:HomePage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
</Application.MainPage>
</Application>
Create FlyoutMenuPage
Create a new page FlyoutMenuPage.xaml
for the flyout menu.
<!--FlyoutMenuPage.xaml-->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:YourNamespace"
x:Class="YourNamespace.FlyoutMenuPage"
Title="Menu">
<ContentPage.Content>
<ListView SeparatorVisibility="FormattableString">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
Code-Behind for FlyoutMenuPage
Modify FlyoutMenuPage.xaml.cs
to handle item selection.
public partial class FlyoutMenuPage : ContentPage
{
List<Page> pages;
ListView listView;
public FlyoutMenuPage()
{
InitializeComponent();
pages = new List<Page>
{
new HomePage { Title = "Home" },
new SettingsPage { Title = "Settings" }
};
var cell = new DataTemplate(typeof(TextCell));
cell.SetBinding(TextCell.TextProperty, "Title");
listView = new ListView
{
ItemsSource = pages,
ItemTemplate = cell
};
listView.ItemSelected += OnItemSelected;
Content = listView;
}
void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (sender is ListView listView && e.SelectedItem is Page page)
{
(Parent as FlyoutPage).Detail = new NavigationPage(page);
listView.SelectedItem = null;
}
(Parent as FlyoutPage).IsPresented = false;
}
}
Step 3: Running the Application
Now that we have set up both TabbedPage
and FlyoutPage
, it's time to run the application.
- Select the target platform from the toolbar (e.g., Windows, Android Emulator).
- Click the Start button or press F5 to build and run your application.
- Your app should open with the
TabbedPage
orFlyoutPage
, depending on your setup, and you can navigate between the pages.
Step 4: Data Flow
Understanding data flow is crucial when working with .NET MAUI applications.
Binding Data in XAML
XAML provides a declarative way to bind the user interface to the underlying data.
<Label Text="{Binding WelcomeMessage}"
HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
ViewModel
Create a ViewModel
class to hold your data and logic.
public class HomePageViewModel
{
public string WelcomeMessage { get; set; } = "Welcome to the Home Page!";
}
Set the BindingContext
to your ViewModel
.
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
BindingContext = new HomePageViewModel();
}
}
Data Binding Events
Events in XAML can be bound to methods in your ViewModel.
<Button Text="Click Me!"
Clicked="{Binding OnButtonClick}" />
public class HomePageViewModel : INotifyPropertyChanged
{
private string _welcomeMessage;
public string WelcomeMessage
{
get => _welcomeMessage;
set
{
_welcomeMessage = value;
OnPropertyChanged(nameof(WelcomeMessage));
}
}
public ICommand OnButtonClick => new Command(() =>
{
WelcomeMessage = "Button Clicked!";
});
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Conclusion
In this guide, you have learned how to set up routes and run your .NET MAUI application using two fundamental page types: TabbedPage
and FlyoutPage
. You've also seen how to manage data flow through data binding and ViewModel interaction. With this knowledge, you can start building more complex and responsive applications using .NET MAUI.
Additional Resources
By following this step-by-step guide, you should be well on your way to becoming proficient in working with .NET MAUI page types and data flow mechanisms. Happy coding!
Top 10 Questions and Answers on .NET MAUI Page Types: TabbedPage & FlyoutPage
1. What is .NET MAUI, and how does it relate to TabbedPage and FlyoutPage?
Answer: .NET Multi-platform App UI (.NET MAUI) is a powerful cross-platform framework for constructing native user interfaces for mobile and desktop applications using C# and XAML. It allows developers to create a single, shared codebase that runs across various platforms without needing to write platform-specific code. TabbedPage
and FlyoutPage
are two important page types in .NET MAUI that help in organizing and navigating through different parts of an application.
- TabbedPage: This provides a way to organize content into tabs. Each tab corresponds to a page, and users can switch between content by selecting different tabs.
- FlyoutPage: Ideal for master-detail layouts, this type of page offers a flyout menu (master page) that users can slide out from the side to access different areas of the app, while the detail page displays the selected content.
2. What is TabbedPage, and when would you use it?
Answer: TabbedPage
is used when you need to present a set of pages arranged in a tabs container, allowing users to switch between different sections of the application easily. It is particularly useful for scenarios like:
- User Dashboard: Present different user-related sections, such as Profile, Settings, and Notifications.
- News Application: Organize topics into separate tabs such as Local News, National News, and International News.
- Product Catalog: Categorize products by type (e.g., Electronics, Books, Clothing).
Here is an example code snippet for creating a TabbedPage
:
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
var tab1 = new MyContentPage { Title = "Tab 1" };
var tab2 = new MyContentPage { Title = "Tab 2" };
var tab3 = new MyContentPage { Title = "Tab 3" };
Children.Add(tab1);
Children.Add(tab2);
Children.Add(tab3);
}
}
3. Can you explain how to customize the appearance of TabbedPage's tabs?
Answer: Yes, the appearance of tabs in a TabbedPage
can be customized by adjusting properties of each individual tab or by setting styles globally. Here are some customization options:
- Icon Images: Add icons to tabs using the
IconImageSource
property. - Title Colors: Change the colors of titles using the
BarTextColors
property. - Background Colors: Adjust the background colors using
BarBackgroundColor
. - Styles: Apply styles to the
TabbedPage
to maintain a consistent look across the application.
Here is how you can set some properties:
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
BarBackgroundColor = Color.FromHex("#1B2A47");
BarTextColor = Color.White;
Children.Add(new MyContentPage
{
Title = "Tab 1",
IconImageSource = "icon.png"
});
// Add more tabs...
}
}
4. How does FlyoutPage differ from TabbedPage in .NET MAUI?
Answer: While both TabbedPage
and FlyoutPage
help in organizing navigation, they serve different purposes:
- TabbedPage: Best for when there are multiple top-level navigation options that can be easily accessed via tabs at the bottom or top of the screen.
- FlyoutPage: Useful for creating a side menu for accessing different sections of the app, especially when there are many options or the application has a more hierarchical structure.
FlyoutPage
consists of two main components:
- Flyout (Master Page): A side menu that can be toggled in and out from the left or right side of the screen.
- Detail (Detail Page): Contains the content of the currently selected item in the flyout menu.
5. Can you provide an example of how to implement a FlyoutPage in .NET MAUI?
Answer: Sure, here’s how to create a simple FlyoutPage
:
public class MyFlyoutPage : FlyoutPage
{
public MyFlyoutPage()
{
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
Flyout = new FlyoutMenu();
Detail = new NavigationPage(new HomePage());
}
}
public class FlyoutMenu : ContentPage
{
public FlyoutMenu()
{
Title = "Menu";
Content = new StackLayout
{
Children = {
new Button { Text = "Home", Command = new Command(navigateToHome) },
new Button { Text = "Settings", Command = new Command(navigateToSettings) }
}
};
}
private void navigateToHome(object obj)
{
((FlyoutPage)Application.Current.MainPage).Detail = new NavigationPage(new HomePage());
((FlyoutPage)Application.Current.MainPage).IsPresented = false;
}
private void navigateToSettings(object obj)
{
((FlyoutPage)Application.Current.MainPage).Detail = new NavigationPage(new SettingsPage());
((FlyoutPage)Application.Current.MainPage).IsPresented = false;
}
}
6. What are the benefits of using FlyoutPage over TabbedPage?
Answer: FlyoutPage
provides several advantages:
- Space Efficiency: Saves screen real estate compared to multiple tabs at the bottom or top, which is particularly beneficial on smaller screens.
- Hierarchical Navigation: Facilitates more complex navigation structures with multiple levels of navigation.
- User Experience: Can offer a richer user experience by providing easy access to a variety of options, organized in a menu, leading to a more intuitive interface.
7. How can you handle navigation within a TabbedPage or FlyoutPage?
Answer: Navigation within TabbedPage
or FlyoutPage
can be managed using the Navigation
property, which is available in NavigationPage
instances. Here’s how you can handle navigation in each type of page:
TabbedPage:
var tabbedPage = new MyTabbedPage();
tabbedPage.CurrentPage = tabbedPage.Children[1]; // Switches to the second tab
FlyoutPage:
public partial class FlyoutMenu : ContentPage
{
public FlyoutMenu()
{
Title = "Menu";
Content = new StackLayout
{
Children = {
new Button
{
Text = "Home",
Command = new Command(() => navigateToPage(new HomePage()))
},
new Button
{
Text = "Settings",
Command = new Command(() => navigateToPage(new SettingsPage()))
}
}
};
}
private void navigateToPage(Page page)
{
((FlyoutPage)Application.Current.MainPage).Detail
= new NavigationPage(page);
((FlyoutPage)Application.Current.MainPage).IsPresented = false;
}
}
8. Can you add nested navigation to a TabbedPage or FlyoutPage?
Answer: Yes, nested navigation can be added by encapsulating individual tabs or the detail page within a NavigationPage
. This allows users to push new pages onto the navigation stack, enabling a deeper level of navigation within tabs or the detail section of a FlyoutPage
.
Here’s an example of adding nested navigation to a TabbedPage
:
public class MyTabbedPage : TabbedPage
{
public MyTabbedPage()
{
var tab1 = new NavigationPage(new Tab1Page()) { Title = "Tab 1" };
var tab2 = new NavigationPage(new Tab2Page()) { Title = "Tab 2" };
var tab3 = new NavigationPage(new Tab3Page()) { Title = "Tab 3" };
Children.Add(tab1);
Children.Add(tab2);
Children.Add(tab3);
}
}
For a FlyoutPage
:
public class MyFlyoutPage : FlyoutPage
{
public MyFlyoutPage()
{
Flyout = new FlyoutMenu();
Detail = new NavigationPage(new HomePage());
}
}
9. How can you handle back button behavior in a TabbedPage or FlyoutPage?
Answer: Handling the back button behavior in TabbedPage
or FlyoutPage
is essential to ensure a smooth and intuitive user experience. When using nested navigation, pressing the back button should navigate back to the previous page within the current tab or detail section. Here are some strategies for managing the back button:
TabbedPage:
- Each tab could be a
NavigationPage
, allowing individual stack management within each tab. - Ensure that the back button navigates within the current tab before switching to another tab.
FlyoutPage:
- The detail section should handle back navigation independently.
- You might need to handle back button presses manually if you want to control the behavior more precisely.
Here’s an example of handling back button presses in a FlyoutPage
:
protected override bool OnBackButtonPressed()
{
// Attempt to navigate back within the detail page
if (((NavigationPage)Detail).Navigation.NavigationStack.Count > 1)
{
((NavigationPage)Detail).Navigation.PopAsync();
return true; // Indicates that the back button was handled
}
// Default behavior: Do nothing
return base.OnBackButtonPressed();
}
10. What are some common practices for optimizing the performance of complex navigation structures involving TabbedPage and FlyoutPage?
Answer: Designing efficient and performant navigation structures in complex layouts like those involving TabbedPage
and FlyoutPage
involves several best practices:
- Lazy Loading: Load content only when necessary, especially in scenarios where tabs or menu items contain heavy or resource-intensive views.
- Efficient Binding: Use data binding effectively to minimize manual UI updates and improve performance.
- Caching: Cache pages or views if they are reused frequently to avoid redundant loading and rendering.
- Synchronous Content: Avoid loading content asynchronously on the UI thread to prevent UI freezes.
- Profiling and Testing: Regularly profile your application to identify bottlenecks and test navigation flows thoroughly to ensure smooth performance.
By adhering to these guidelines and strategies, you can create robust and efficient TabbedPage
and FlyoutPage
navigation structures that enhance the user experience and performance of your .NET MAUI applications.