我正在尝试使用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
,因为属性是不可能的。这是正确的还是我的代码有问题?
答案 0 :(得分:1)
您需要在此处使用嵌套的标记扩展名(您已经这样做了);但您还需要指定属性名称。否则,我的测试表明,它将被视为字符串值并分配给默认的content属性-因此,类型不匹配。
因此,按如下所示明确指定属性名称应该可以解决该问题:
<Label Text="{local:TypeMarkup TheType={x:Type x:Int16}}" ../>
您可以使用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";
}
}