Markup Extensions

Uno Platform supports the MarkupExtension class, which gives the ability to enhance the XAML-first experience.

Support for ProvideValue()

Given the following code:

using System;
using System.Collections.Generic;
using System.Text;
using Windows.UI.Xaml.Markup;

namespace MyMarkupExtension;

[MarkupExtensionReturnType(ReturnType = typeof(string))]
public class Simple : Windows.UI.Xaml.Markup.MarkupExtension
{
    public string TextValue { get; set; }

    protected override object ProvideValue()
    {
        return TextValue + " markup extension";
    }
}

This class can be used as follows in the XAML:

<Grid xmlns:ex="using:MyMarkupExtension">
    <TextBlock Text="{ex:Simple TextValue='Just a simple '}"
                FontSize="16"
                Margin="0,0,0,40" />
</Grid>

Support for ProvideValue(IXamlServiceProvider)

WinUI 3 provides enhanced support for MarkupExtension with the ability to get the markup context.

Note

While this feature is available on all Uno Platform targets (UWP and WinUI), the UWP head on Windows does not support this feature, only the WinAppSDK head supports it.

IProvideValueTarget

using System;
using System.Collections.Generic;
using System.Text;
using Windows.UI.Xaml.Markup;

namespace MyMarkupExtension;

public class SampleProvideValueTarget : MarkupExtension
{
    protected override object ProvideValue(IXamlServiceProvider serviceProvider)
    {
        var provideValueTarget = (IProvideValueTarget)context.GetService(typeof(IProvideValueTarget));

        return $"TargetProperty:{provideValueTarget.TargetProperty}, TargetObject:{provideValueTarget.TargetObject}";
    }
}

This class can be used as follows in the XAML:

<Grid xmlns:ex="using:MyMarkupExtension">
    <TextBlock Text="{ex:SampleProvideValueTarget}"
                FontSize="16"
                Margin="0,0,0,40" />
</Grid>

IRootObjectProvider

With access to IRootObjectProvider becomes possible for a Markup extension to browse the visual tree, starting from the root of the XAML file.

This following example from the WinUI specifications give a glimpse of this feature.

Using the following XAML:

public class DynamicBindExtension : MarkupExtension
{
    public DynamicBindExtension() { }

    public string Name { get; set; } = "";

    protected override object? ProvideValue(IXamlServiceProvider serviceProvider)
    {
        var root = ((IRootObjectProvider)serviceProvider.GetService(typeof(IRootObjectProvider))).RootObject;
        var info = root.GetType().GetProperty(Name);
        return info?.GetValue(root);
    }
}

The following XAML will display “Page Tag”:

<Page Tag='Page tag' 
      x:Class="App1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App52"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ContentControl>
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{local:DynamicBind Name=Tag}" />
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>
    </Grid>
</Page>

IUriContext

Not supported as of Uno 4.3

IXamlTypeResolver

Not supported as of Uno 4.3