Search code examples
c#.netxamluwpmarkup-extensions

Equivalent of x:Type in UWP


I have this class:

public class EditorKey
{
    public Type TargetType { get; set; }
    public DataTemplate Template { get; set; }
}

Now, I want to create an instance of this class in XAML. Since in UWP we don't have the x:Type markup extension, I'm specifying the type directly as a string, with the correct prefix with TargetType="model:Customer"

<Page
    x:Class="App8.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:model="using:App8"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <ContentControl>
        <model:EditorKey TargetType="model:Customer" />
    </ContentControl>

</Page>

Running this, I get a runtime exception:

Failed to create a 'App8.EditorKey' from the text 'model:Customer'.

How can I map the string to the actual Type?


Solution

  • The usual way of doing it in UWP is to simply supply the reference as a string:

    <model:EditorKey TargetType="model:Customer" />
    

    If this doesn't work, try specifying the full namespace, rather than defining an xmlns.

    Example:

    <model:EditorKey TargetType="App8.Customer" />
    

    Note: As of time of writing, there's an issue where the above will crash in Release mode. As a workaround, you can create a Markup extension:

    [MarkupExtensionReturnType(ReturnType = typeof(Type))]
    public sealed class TypeExtension : MarkupExtension
    {
        public Type Type { get; set; }
    
        /// <inheritdoc/>
        protected override object ProvideValue() => Type;
    }
    

    And use it like so:

    <model:EditorKey TargetType="{local:Type Type='App8.Customer'"/>