acuamitca.com logo ACUAMITCA
~/blog/article

Custom Markup Extensions in .NET MAUI

.Net MAUI 8 mins read August 07, 2026
 

Markup extensions in XAML are powerful tools that allow you to extend the XAML language with custom functionality. They enable you to create complex, reusable logic that can be applied directly in your UI markup, making your code cleaner and more maintainable .

⚡ Key Insight: Custom markup extensions can simplify repetitive UI code, enable data transformations, and create powerful developer experiences in XAML.


What Are Markup Extensions?

Markup extensions are a feature in XAML that allow you to evaluate expressions at runtime. They are typically used to provide values for attributes in XAML that cannot be determined at compile time .

Common built-in markup extensions include {Binding}, {StaticResource}, {DynamicResource}, and {x:Static}. Custom markup extensions let you create your own reusable expression syntax for domain-specific needs.

<!-- Common built-in markup extensions -->
<Label Text="{Binding UserName}" />
<Button BackgroundColor="{StaticResource PrimaryColor}" />
<Label Text="{x:Static local:AppConstants.AppName}" />

Creating a Custom Markup Extension

A custom markup extension is a class that inherits from MarkupExtension or MarkupExtension<T>. Let's build a custom extension that applies a gradient to UI elements .

using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;

namespace ACUAMITCA.Extensions
{
    public class GradientExtension : IMarkupExtension<GradientBrush>
    {
        public Color StartColor { get; set; }
        public Color EndColor { get; set; }
        public double Angle { get; set; } = 0;

        public GradientBrush ProvideValue(IServiceProvider serviceProvider)
        {
            var gradient = new LinearGradientBrush
            {
                StartPoint = new Point(0, 0),
                EndPoint = new Point(1, 1)
            };

            gradient.GradientStops.Add(new GradientStop(StartColor, 0f));
            gradient.GradientStops.Add(new GradientStop(EndColor, 1f));

            return gradient;
        }

        object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
        {
            return ProvideValue(serviceProvider);
        }
    }
}

Using the Custom Markup Extension

<!-- In your XAML -->
<ContentPage xmlns:ext="clr-namespace:ACUAMITCA.Extensions">
    <Button Text="Gradient Button">
        <Button.Background>
            <ext:GradientExtension StartColor="#6366F1" EndColor="#8B5CF6" />
        </Button.Background>
    </Button>
</ContentPage>

💡 Pro Tip: Use IMarkupExtension<T> instead of the non-generic IMarkupExtension for better type safety and simpler implementation .


Advanced Example: Image Filter Markup Extension

A more complex use case is creating a markup extension that applies custom filters to images. This approach was used in an image filter application that applied gradient filters to photos .

public class ImageFilterExtension : IMarkupExtension<Image>
{
    public string SourcePath { get; set; }
    public string FilterType { get; set; } = "Grayscale";

    public Image ProvideValue(IServiceProvider serviceProvider)
    {
        var image = new Image
        {
            Source = ImageSource.FromFile(SourcePath)
        };

        // Apply filter based on FilterType
        switch (FilterType)
        {
            case "Grayscale":
                // Apply grayscale filter logic
                break;
            case "Blur":
                // Apply blur filter logic
                break;
            case "Sepia":
                // Apply sepia filter logic
                break;
        }

        return image;
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return ProvideValue(serviceProvider);
    }
}

Best Practices

✅ Keep Extensions Focused

Each markup extension should do one thing and do it well.

✅ Handle Null/Invalid Inputs

Always provide fallback values for invalid inputs.

✅ Use Proper Namespaces

Define your extensions in a dedicated namespace and import it in XAML.

✅ Consider Performance

Avoid heavy operations in markup extensions as they execute during XAML parsing.


Conclusion

📌 Key Takeaway: Custom markup extensions are a powerful way to create reusable, expressive XAML code. They can simplify complex UI logic, reduce code duplication, and make your XAML more maintainable .