Customize your MAUI Experience
Customizing controls in .NET MAUI is a powerful way to tailor your application’s appearance and behavior to meet unique design or functionality requirements. As a cross-platform framework, MAUI provides both shared and platform-specific approaches to extend or enhance controls like Entry, Button, or ListView. With features such as VisualStateManager, Custom Handlers, and Platform Effects, developers can seamlessly adapt their controls to align with branding guidelines, optimize usability, and create visually compelling interfaces. This flexibility makes .NET MAUI an excellent choice for building applications that stand out while still leveraging the benefits of a unified codebase.
Create a Custom Entry Handler
Let’s customize an Entry to change its border color, border width, and corner radius by mapping properties to the native platform controls.
1. Create a Custom Entry Class
Define a custom Entry class with bindable properties for customization.
using Microsoft.Maui.Controls;
public class CustomEntry : Entry
{
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(CustomEntry), Colors.Transparent);
public static readonly BindableProperty BorderWidthProperty =
BindableProperty.Create(nameof(BorderWidth), typeof(int), typeof(CustomEntry), 1);
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create(nameof(CornerRadius), typeof(int), typeof(CustomEntry), 5);
public Color BorderColor
{
get => (Color)GetValue(BorderColorProperty);
set => SetValue(BorderColorProperty, value);
}
public int BorderWidth
{
get => (int)GetValue(BorderWidthProperty);
set => SetValue(BorderWidthProperty, value);
}
public int CornerRadius
{
get => (int)GetValue(CornerRadiusProperty);
set => SetValue(CornerRadiusProperty, value);
}
}
2. Create a Custom Entry Handler
Implement a custom handler to map the new properties to platform-specific controls.
Android Customization
Customize the EditText in Android:
using Microsoft.Maui.Handlers;
using Android.Graphics.Drawables;
using Android.Graphics;
public class CustomEntryHandler : EntryHandler
{
protected override void ConnectHandler(AppCompatEditText platformView)
{
base.ConnectHandler(platformView);
UpdateBorder((CustomEntry)VirtualView);
}
public static void MapBorderColor(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
public static void MapBorderWidth(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
public static void MapCornerRadius(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
private void UpdateBorder(CustomEntry entry)
{
if (PlatformView != null)
{
var drawable = new GradientDrawable();
drawable.SetShape(ShapeType.Rectangle);
drawable.SetStroke(entry.BorderWidth, entry.BorderColor.ToAndroid());
drawable.SetCornerRadius(entry.CornerRadius);
PlatformView.SetBackground(drawable);
}
}
}
iOS Customization
Customize the UITextField in iOS:
using Microsoft.Maui.Handlers;
using UIKit;
using CoreGraphics;
public class CustomEntryHandler : EntryHandler
{
protected override void ConnectHandler(MauiTextField platformView)
{
base.ConnectHandler(platformView);
UpdateBorder((CustomEntry)VirtualView);
}
public static void MapBorderColor(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
public static void MapBorderWidth(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
public static void MapCornerRadius(CustomEntryHandler handler, CustomEntry entry)
{
handler.UpdateBorder(entry);
}
private void UpdateBorder(CustomEntry entry)
{
if (PlatformView != null)
{
PlatformView.Layer.BorderColor = entry.BorderColor.ToCGColor();
PlatformView.Layer.BorderWidth = entry.BorderWidth;
PlatformView.Layer.CornerRadius = entry.CornerRadius;
}
}
}
3. Register the Custom Handler
Update the MauiProgram.cs to register the custom handler.
using Microsoft.Maui.Controls.Hosting;
using Microsoft.Maui.Hosting;
#if ANDROID
using <Namespace Android Platform>;
#endif
#if IOS
using <Namespace iOS Platform>;
#endif
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler<CustomEntry, CustomEntryHandler>();
});
return builder.Build();
}
}
4. Use the Custom Entry in XAML
Now, you can use the CustomEntry with its custom properties directly in XAML.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:YourAppNamespace"
x:Class="YourAppNamespace.MainPage">
<StackLayout Padding="20">
<local:CustomEntry
Placeholder="Enter text here"
BorderColor="Blue"
BorderWidth="2"
CornerRadius="10"
TextColor="Black"
WidthRequest="300"
HeightRequest="50" />
</StackLayout>
</ContentPage>
Output
This example demonstrates the flexibility of .NET MAUI in creating reusable, cross-platform customizations while retaining platform-specific fine-tuning.