Xamarin自定义MarkupExtension不适用于Type属性

时间:2018-08-24 14:19:19

标签: c# xaml xamarin xamarin.forms

我正在尝试使用Type作为属性以Xamarin形式创建自定义MarkupExtension。不幸的是,我无法传递属性Type,在我的情况下,该属性始终为null。这是我的MarkupExtension的最小示例,将类型的全名重命名为字符串:

[ContentProperty(nameof(TheType))]
public class TypeMarkupExtension : IMarkupExtension
{
    public Type TheType { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {

        return TheType?.FullName ?? "Failure";
    }
}

但是我无法尝试使用MarkupExtension,因为TheType始终为null,返回值为"Failure"。这是我尝试使用扩展名的方式:

<Label Text="{local:TypeMarkup x:Int16}"/>
<Label Text="{local:TypeMarkup {x:Type x:Int16}}"/>

如果我使用简单的string作为属性类型,则代码可以完美运行。对我来说,似乎无法传递Type,因为属性是不可能的。这是正确的还是我的代码有问题?

1 个答案:

答案 0 :(得分:1)

选项1:指定属性名称

您需要在此处使用嵌套的标记扩展名(您已经这样做了);但您还需要指定属性名称。否则,我的测试表明,它将被视为字符串值并分配给默认的content属性-因此,类型不匹配。

因此,按如下所示明确指定属性名称应该可以解决该问题:

<Label Text="{local:TypeMarkup TheType={x:Type x:Int16}}" ../>

选项2:使用Xaml类型解析器

您可以使用XamlTypeResolver(参考:TypeExtension in Xamarin.Forms

[ContentProperty(nameof(TheType))]
public class TypeMarkupExtension : IMarkupExtension
{
    public string TheType { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
        if (string.IsNullOrEmpty(TheType))
            throw new InvalidOperationException("TheType isn't set.");

        if (serviceProvider == null)
            throw new ArgumentNullException(nameof(serviceProvider));

        var typeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
        if (typeResolver == null)
            throw new ArgumentException("No IXamlTypeResolver in IServiceProvider");

        var resolvedType = typeResolver.Resolve(TheType, serviceProvider);
        return resolvedType?.FullName ?? "Failure";
    }
}