Mastering the PIN Code Page in .NET MAUI: A Comprehensive Guide

Welisson Arley
6 min readJul 16, 2023

--

In the world of modern application development, security is essential. One common security feature used in many applications is the PIN Code Page, which adds an extra layer of protection. In this tutorial, we will explore how to effectively implement and utilize the PIN Code Page in your .NET MAUI.

Example of PIN Code Page available on this NuGet package (Image by author)

Prerequisites

To follow along with this tutorial, I’m assuming that you have a basic understanding of .NET MAUI and have a development environment set up. Additionally, a knowledge of XAML and C#.

Step 1: Installation

To use this package, simply install the NuGet package PinCodes.Authorization.Maui in your .NET MAUI project. In Visual Studio, you can do this by right-clicking on your project and selecting “Manage NuGet Packages”. From there, search for “PinCodes.Authorization.Maui” and install the latest version.

dotnet add package PinCodes.Authorization.Maui

Once the package is installed, you can add a PIN Code Page to your application.

The link for the GitHub repository:

https://github.com/welissonArley/Packages.MAUI/tree/master/src/PinCodes.Authorization

Step 2: Usage

Create a new ContentPage in your .NET MAUI project and add a reference to the CodePage namespace in your file:

xmlns:pinCodeAuthorization="clr-namespace:PinCodes.Authorization.Views.Pages;assembly=PinCodes.Authorization.Maui"

Now, instead of having a ContentPage in your XAML file, you need to change it to:

<?xml version="1.0" encoding="utf-8" ?>
<pinCodeAuthorization:CodePage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pinCodeAuthorization="clr-namespace:PinCodes.Authorization.Views.Pages;assembly=PinCodes.Authorization.Maui"
x:Class="MAUI.App.Views.MyPinCodePage">

</pinCodeAuthorization:CodePage>

And the code-behind to:

public partial class MyPinCodePage : PinCodes.Authorization.Views.Pages.CodePage
{
public MyPinCodePage()
{
InitializeComponent();
}
}

Step 3: Configuring the command callback

The PIN Code package exposes a command callback property that allows you to handle specific events or actions triggered once the user provides the entire code. To configure that, you can use a ViewModel and within your XAML file add the following property:

CallbackCodeFinished="{Binding UserEndTheCodeCommand}"

So your XAML file will look like:

<pinCodeAuthorization:CodePage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModel="clr-namespace:Packages.MAUI.App.ViewModels.PinCodes"
x:DataType="viewModel:PinCodeViewModel"
CallbackCodeFinished="{Binding UserCompletedCodeCommand}">

<!-- Now, we'll add a header, the CodeViewer, and the keyboard to the page's content. -->

</pinCodeAuthorization:CodePage>

And your ViewModel will look like:

public partial class PinCodeViewModel : ObservableObject
{
[RelayCommand]
public void UserCompletedCode(string code)
{
//do something with the code response
}
}

Customizing the Appearance

This package provides several ways to customize the appearance of the PIN Code Page to fit the look and feel of your application. You can customize the colors and the page’s elements.

Header (Above the PinCode Viewer)

You can customize the header on your page by passing it as a StackLayout (e.g., VerticalStackLayout, HorizontalStackLayout). This allows you to include images, labels, commands, and other UI elements, providing complete control over the header’s content and layout. To set up your header, use the Header property within CodePage.

<pinCodeAuthorization:CodePage.Header>
<VerticalStackLayout Margin="0,20,0,40" Spacing="5">
<Label
FontAttributes="Bold"
FontSize="36"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Text="Verify Phone"
TextColor="{AppThemeBinding Light=Black,
Dark=White}" />

<Label
FontAttributes="Italic"
FontSize="14"
HorizontalOptions="Center"
Text="code has been sent to +351 912345678"
TextColor="{AppThemeBinding Light=Black,
Dark=White}" />
</VerticalStackLayout>
</pinCodeAuthorization:CodePage.Header>

SubHeader (Below the PinCode Viewer)

You have the option to add a subheader to display more information beneath the code viewer component. Utilize the StackLayout (such as VerticalStackLayout or HorizontalStackLayout) to customize the subheader’s look and functionality according to your requirements.

<pinCodeAuthorization:CodePage.SubHeader>
<VerticalStackLayout Margin="0,30,0,20" HorizontalOptions="Center">
<Label
Margin="0,0,0,20"
FontSize="16"
Text="Didn't get the verification code?" />

<VerticalStackLayout
Padding="0,5,0,5"
HeightRequest="40"
HorizontalOptions="Center">
<VerticalStackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ResendCodeCommand}" />
</VerticalStackLayout.GestureRecognizers>
<Label
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="Center"
Text="Resend code"
TextColor="{AppThemeBinding Light=#007AFF,
Dark=#19B5FE}" />
</VerticalStackLayout>
</VerticalStackLayout>
</pinCodeAuthorization:CodePage.SubHeader>

Code Viewer

The first step is to reference the CodeViewer component namespace in your XAML file:

xmlns:codeViewer="clr-namespace:PinCodes.Authorization.Views.Components.CodeViewers;assembly=PinCodes.Authorization.Maui"

Now it’s time to use the CodeViewer property. It’s important to decide whether you want to hide or show the code, as this will determine which component to use in the XAML.

If you want to hide it, add:

<pinCodeAuthorization:CodePage.CodeViewer>
<codeViewer:HideCodeViewer>
<!-- CUSTOMIZATION HERE -->
</codeViewer:HideCodeViewer>
</pinCodeAuthorization:CodePage.CodeViewer>

but if you want to show the PIN Code, use:

<pinCodeAuthorization:CodePage.CodeViewer>
<codeViewer:ShowCodeViewer>
<!-- CUSTOMIZATION HERE -->
</codeViewer:ShowCodeViewer>
</pinCodeAuthorization:CodePage.CodeViewer>

Let’s discuss the customization of the CodeViewer. Whether you choose to hide or show the code, the following properties are the same for both options:

  • CodeLength: Specifies the size of the code (default is 4).
  • Spacing: Defines the spacing between elements that represent each character of the code.
  • ShapeViewer: An abstract class that enables you to draw a shape on the screen. You can pass a concrete type like Ellipse, Rectangle, etc.
  • CodeColor: Specifies the color to fill the shape when there is a code character for the component. By default, the color specified for the shape will be used when the element representing the code character is empty.
  • CodeStrokeColor: Specifies the color for the shape stroke when there is a code character for the component. By default, the color stroke specified for the shape will be used when the element representing the code character is empty.

If you choose to show the code as the user types, you need to use the PinCharacterLabel property. This is a label that you must pass to the library to specify how you want to display the number. Feel free to use all properties available on the label, such as FontSize, FontColor, etc.

Below is an example demonstrating how easy it is to define the properties:

<pinCodeAuthorization:CodePage.CodeViewer>
<codeViewer:ShowCodeViewer CodeColor="{AppThemeBinding Light=White, Dark={StaticResource DarkModeColor}}" CodeStrokeColor="{AppThemeBinding Light=Black, Dark=White}">
<codeViewer:ShowCodeViewer.ShapeViewer>
<RoundRectangle
CornerRadius="10"
Fill="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
HeightRequest="50"
Stroke="{AppThemeBinding Light=Black,
Dark=White}"
StrokeThickness="5"
WidthRequest="50" />
</codeViewer:ShowCodeViewer.ShapeViewer>

<codeViewer:ShowCodeViewer.PinCharacterLabel>
<Label
FontAttributes="Bold"
FontSize="16"
HorizontalOptions="Center"
TextColor="{AppThemeBinding Light=Black,
Dark=White}"
VerticalOptions="Center" />
</codeViewer:ShowCodeViewer.PinCharacterLabel>
</codeViewer:ShowCodeViewer>
</pinCodeAuthorization:CodePage.CodeViewer>

Keyboard

You must use the Keyboard property available on the CodePage to select the appearance of the keyboard buttons, depending on the look and feel you want to achieve. Don’t forget to add the namespace on your XAML file:

xmlns:keyboardViewer="clr-namespace:PinCodes.Authorization.Views.Components.Keyboards;assembly=PinCodes.Authorization.Maui"

The keyboard view has several properties for customization, with two being mandatory (ShapeViewer & BackspaceViewer) and the others optional:

  • ShapeViewer: Use this property to define the appearance of the buttons for the numbers. Feel free to choose the size, colors, etc.
  • BackspaceViewer: You can pass a Button or an ImageButton to be displayed as the backspace option for the keyboard.
  • LeftSideButtonShapeViewer: You can pass a Button or an ImageButton to be displayed as an option on the left side of the number 0. This button is optional; if you don’t pass it, the left side of the number 0 will be empty.
  • RowSpacing: Defines the spacing between each line of the keyboard.
  • ColumnSpacing: Defines the spacing between each column of the keyboard.

Below is an example demonstrating how easy it is to define the properties:

<pinCodeAuthorization:CodePage.Keyboard>
<keyboardViewer:KeyboardViewer ColumnSpacing="40" RowSpacing="20">
<keyboardViewer:KeyboardViewer.ShapeViewer>
<Button
BackgroundColor="Transparent"
FontAttributes="Bold"
FontSize="24"
HeightRequest="80"
TextColor="{AppThemeBinding Light=Black,
Dark=White}"
WidthRequest="80" />
</keyboardViewer:KeyboardViewer.ShapeViewer>

<keyboardViewer:KeyboardViewer.BackspaceViewer>
<ImageButton
Padding="22"
BackgroundColor="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
Source="illustration_delete.png" />
</keyboardViewer:KeyboardViewer.BackspaceViewer>

<keyboardViewer:KeyboardViewer.LeftSideButtonShapeViewer>
<ImageButton
Padding="22"
BackgroundColor="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
Command="{Binding FaceIdCommand}"
Source="illustration_faceid.png" />
</keyboardViewer:KeyboardViewer.LeftSideButtonShapeViewer>
</keyboardViewer:KeyboardViewer>
</pinCodeAuthorization:CodePage.Keyboard>

How to clear the PinCode?

Imagine that when you receive the code via the callback command, you determine that the code is incorrect. You will want to clear the PIN code and prompt the user to input it again, right? To achieve this, simply call the following line of code from your ViewModel or in the Page with CodeBehind (both methods work):

PinCodeAuthorizationCenter.ClearPinCode();

Full XAML code

<pinCodeAuthorization:CodePage
x:Class="Packages.MAUI.App.Views.PinCodes.PinCodePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:codeViewer="clr-namespace:PinCodes.Authorization.Views.Components.CodeViewers;assembly=PinCodes.Authorization.Maui"
xmlns:keyboardViewer="clr-namespace:PinCodes.Authorization.Views.Components.Keyboards;assembly=PinCodes.Authorization.Maui"
xmlns:pinCodeAuthorization="clr-namespace:PinCodes.Authorization.Views.Pages;assembly=PinCodes.Authorization.Maui"
xmlns:viewModel="clr-namespace:Packages.MAUI.App.ViewModels.PinCodes"
x:DataType="viewModel:PinCodeViewModel"
CallbackCodeFinished="{Binding BindingContext.UserCompletedCodeCommand, Source={x:Reference PagePinCode}}">

<pinCodeAuthorization:CodePage.Header>
<VerticalStackLayout Margin="0,20,0,40" Spacing="5">
<Label
FontAttributes="Bold"
FontSize="36"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Text="Verify Phone"
TextColor="{AppThemeBinding Light=Black,
Dark=White}" />

<Label
FontAttributes="Italic"
FontSize="14"
HorizontalOptions="Center"
Text="code has been sent to +351 912345678"
TextColor="{AppThemeBinding Light=Black,
Dark=White}" />
</VerticalStackLayout>
</pinCodeAuthorization:CodePage.Header>

<pinCodeAuthorization:CodePage.SubHeader>
<VerticalStackLayout Margin="0,30,0,20" HorizontalOptions="Center">
<Label
Margin="0,0,0,20"
FontSize="16"
Text="Didn’t get the verification code?" />

<VerticalStackLayout
Padding="0,5,0,5"
HeightRequest="40"
HorizontalOptions="Center">
<VerticalStackLayout.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ResendCodeCommand}" />
</VerticalStackLayout.GestureRecognizers>
<Label
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="Center"
Text="Resend code"
TextColor="{AppThemeBinding Light=#007AFF,
Dark=#19B5FE}" />
</VerticalStackLayout>
</VerticalStackLayout>
</pinCodeAuthorization:CodePage.SubHeader>

<pinCodeAuthorization:CodePage.CodeViewer>
<codeViewer:ShowCodeViewer CodeColor="{AppThemeBinding Light=White, Dark={StaticResource DarkModeColor}}" CodeStrokeColor="{AppThemeBinding Light=Black, Dark=White}">
<codeViewer:ShowCodeViewer.ShapeViewer>
<RoundRectangle
CornerRadius="10"
Fill="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
HeightRequest="50"
Stroke="{AppThemeBinding Light=Black,
Dark=White}"
StrokeThickness="5"
WidthRequest="50" />
</codeViewer:ShowCodeViewer.ShapeViewer>

<codeViewer:ShowCodeViewer.PinCharacterLabel>
<Label
FontAttributes="Bold"
FontSize="16"
HorizontalOptions="Center"
TextColor="{AppThemeBinding Light=Black,
Dark=White}"
VerticalOptions="Center" />
</codeViewer:ShowCodeViewer.PinCharacterLabel>
</codeViewer:ShowCodeViewer>
</pinCodeAuthorization:CodePage.CodeViewer>

<pinCodeAuthorization:CodePage.Keyboard>
<keyboardViewer:KeyboardViewer ColumnSpacing="40" RowSpacing="20">
<keyboardViewer:KeyboardViewer.ShapeViewer>
<Button
BackgroundColor="Transparent"
FontAttributes="Bold"
FontSize="24"
HeightRequest="80"
TextColor="{AppThemeBinding Light=Black,
Dark=White}"
WidthRequest="80" />
</keyboardViewer:KeyboardViewer.ShapeViewer>

<keyboardViewer:KeyboardViewer.BackspaceViewer>
<ImageButton
Padding="22"
BackgroundColor="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
Source="illustration_delete.png" />
</keyboardViewer:KeyboardViewer.BackspaceViewer>

<keyboardViewer:KeyboardViewer.LeftSideButtonShapeViewer>
<ImageButton
Padding="22"
BackgroundColor="{AppThemeBinding Light=White,
Dark={StaticResource DarkModeColor}}"
Command="{Binding FaceIdCommand}"
Source="illustration_faceide.png" />
</keyboardViewer:KeyboardViewer.LeftSideButtonShapeViewer>
</keyboardViewer:KeyboardViewer>
</pinCodeAuthorization:CodePage.Keyboard>

</pinCodeAuthorization:CodePage>

Conclusion

In conclusion, this tutorial has provided a comprehensive guide on how to use MauiCode. By following the step-by-step instructions, you have learned how to install the package, import the necessary namespaces, and use the features to manage PIN Codes. Remember to keep your packages up to date to take advantage of the latest features and improvements. Happy coding and enjoy the added security that PIN Code bring to your projects!

--

--

Welisson Arley
Welisson Arley

Written by Welisson Arley

✨ Senior .NET Developer | .NET MAUI Specialist | Azure DevOps | Team Leader | RESTful API Development | Agile Project Management | Microsoft Azure | .NET Core

Responses (3)