.NET MAUI - Creating a XAML File Menu

Search for a command to run...

No comments yet. Be the first to comment.
In this series I will be building a PDF splitting application for Windows using .NET MAUI.
Introduction In this article, I'm going to introduce basic navigation into my .NET MAUI PDF Splitter application. If you're following my PDF Splitter Application series, you will have a simple application based on the out-the-box .NET template with a...
Introduction Semantic Kernel is an open-source framework by Microsoft that integrates machine learning and natural language processing to build AI applications. It offers tools for tasks like language understanding, text generation, and semantic sear...

Introduction In the earlier articles in my PDF Splitter series, we have relied on the inbuild .NET libraries to handle working with PDF files in MAUI, but these only support opening and displaying of PDF files. Now that we are looking to save our new...

Introduction In the previous article, we created a PDF model and service to allow us to work with and track PDF pages. The next step is to build the UI to allow us to interact with the service. To do this we will create a single 'view' and a 'view mo...

Introduction For the fourth article in my PDF Splitter series, we will start working with PDF files in .NET MAUI. Helpfully, MAUI contains a lot of useful PDF tools for reading PDF files out of the box, so we do not need to use any additional librari...

Introduction In this article, I'm going to introduce basic navigation into my .NET MAUI PDF Splitter application. If you're following my PDF Splitter Application series, you will have a simple application based on the out-the-box .NET template with a...

In this article, I'm going to add a file menu to my .NET MAUI PDF Splitter application.
If you're following my PDF Splitter Application series, you will have a simple application based on the out-the-box .NET template which we will now start to build upon.
If not you can jump to the final code for the series here.
We are going to add a simple menu bar to our application, which has two top-level items (File and About) and some sub-items as outlined below:
File
Open
Close
[Separator]
Exit
About
To add these to our UI we can simply update our AppShell.xaml as follows:
<Shell.MenuBarItems>
<MenuBarItem Text="File">
<MenuFlyoutItem Text="Open" Command="{Binding OnMenuItemClickedCommand}" CommandParameter="Open" />
<MenuFlyoutItem Text="Close" Command="{Binding OnMenuItemClosePdfClickedCommand}" CommandParameter="Close" />
<MenuFlyoutSeparator />
<MenuFlyoutItem Text="Exit" Command="{Binding OnMenuItemClickedCommand}" CommandParameter="Exit" />
</MenuBarItem>
<MenuBarItem Text="About">
<MenuFlyoutItem Text="About" Command="{Binding OnMenuItemAboutClickedCommand}" CommandParameter="About" />
</MenuBarItem>
</Shell.MenuBarItems>
As you can see, each of the items in the file menu (except the separator) is bound to a command. Some are bound to the same command, in this instance both Exit and Open are bound to the OnMenuItemClickedCommand, whereas others are bound to individual commands. The reason for this is dependent on what needs to happen when the command is triggered.
Handling simple events that occur in the UI on the back end of an MAUI application can be done through the use of commands.
The ICommand interface allows us to define commands and what happens when a command is triggered.
For a command implementation, we must provide an implementation of what happens when we trigger that command, in the form of an action parameter.
We can additionally provide a second function parameter, CommandCanExecute which returns whether the command can be triggered or not. This option is used when we want to enable or disable a control based on the current application state. If we omit it, it will always be true.
Finally, we are also able to define a command parameter, which we can pass from the UI into the command itself.
I will use all three options below to define our commands for this application.
As our AppShell.xaml is bound to our AppShellViewModel (see previous article for more details) we need to add our command implementation to our AppShellViewModel.cs file as below:
public class AppShellViewModel
{
public ICommand OnMenuItemClickedCommand { get; private set; }
public ICommand OnMenuItemClosePdfClickedCommand { get; private set; }
public ICommand OnMenuItemAboutClickedCommand { get; private set; }
private bool pdfOpen = false;
public AppShellViewModel()
{
OnMenuItemClickedCommand = new Command<string>(async (s) => await OnMenuItemClicked(s));
OnMenuItemClosePdfClickedCommand = new Command<string>(async (s) => await OnMenuItemClicked(s), (s) => PdfOpen);
OnMenuItemAboutClickedCommand = new Command(DisplayAbout);
}
public async Task OnMenuItemClicked(string item)
{
switch (item) {
case "Exit":
Application.Current.Quit();
break;
case "Open":
break;
case "Close":
break;
default:
break;
}
}
public void DisplayAbout()
{
// Omitted for brevity
}
}
Firstly we define three commands that will implement the ICommand interface.
The first 2 commands (OnMenuItemClickedCommand, OnMenuItemClosePdfClickedCommand), both receive a string command parameter and call the OnMenuItemClicked function, passing that parameter and following the path in the switch statement according to which CommandParameter value was passed in from the UI. For now these don't do anything but we will add more functionality in later stages.
The OnMenuItemClosePdfClickedCommand also provides a second function, which returns the value of the pdfOpen field. As this is initially false, this means that the 'Close' button on our file menu will be disabled when we initially launch our application. One thing to note, if we want to enable our command later, we have to set the pdfOpen field to 'true' but also tell our application to re-evaluate the status of the command by calling:
(OnMenuItemClosePdfClickedCommand as Command).ChangeCanExecute();
We will implement this later in the series when we start to look at opening files.
Finally, our last command OnMenuItemAboutClickedCommand simply calls the DisplayAbout function directly when triggered.
Now we should be able to launch our application and it should display a file menu. In the above code, you can see I have also implemented the 'Exit' code so selecting Exit should quit the application!
The next step is to implement some basic navigation!