忽略"键入本地:MyViewModel 用作标记扩展,但不派生自标记扩展"是否安全?



目标是在没有构造函数注入和静态资源的情况下实例化local:MyViewModel

属性元素语法
<Label.BindingContext>local:MyViewModel</Label.BindingContext>

我尝试使用XML属性语法

<Label ... BindingContext="{local:MyViewModel}"/>

但是Visual Studio Community用

警告我

类型local:MyViewModel用作标记扩展,但不是从MarkupExtension派生的。

问题:

  • 忽略此警告是否安全?
  • 有什么技巧可以抑制警告吗?

这是WPF的标记扩展实现。检查它是否也能在Xamarin中工作。

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Markup;
namespace CommonCore
{
    [MarkupExtensionReturnType(typeof(Type))]
    public class CreateInstanceExtension : MarkupExtension
    {
        [ConstructorArgument("instanceType")]
        [DefaultValue(null)]
        public Type InstanceType { get; set; }
        [ConstructorArgument("instanceValue")]
        [DefaultValue(null)]
        public string InstanceValue { get; set; }
        public CreateInstanceExtension(Type instanceType, string instanceValue)
            : this(instanceValue)
        {
            InstanceType = instanceType;
        }
        public CreateInstanceExtension(string instanceValue)
            : this()
        {
            InstanceValue = instanceValue;
        }
        public CreateInstanceExtension()
        { }
        private static TypeExtension typeExtension;
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            Type type = InstanceType;
            string value = InstanceValue;
            if (type is null)
            {
                value = value?.Trim(" trn".ToCharArray());
                if (!string.IsNullOrEmpty(value))
                {
                    string typeName = null;
                    if (value[0] == '(')
                    {
                        int end = value.IndexOf(')');
                        if (end > 0)
                        {
                            typeName = value.Substring(1, end - 1);
                            value = value.Substring(end + 1).Trim(" trn".ToCharArray());
                        }
                    }
                    else
                    {
                        typeName = value;
                        value = null;
                    }
                    if (!string.IsNullOrEmpty(typeName))
                    {
                        (typeExtension ??= new TypeExtension()).TypeName = typeName;
                        type = (Type)typeExtension.ProvideValue(serviceProvider);
                    }
                }
            }
            if (type is null)
            {
                throw new NullReferenceException("The type must be specified.");
            }
            if (string.IsNullOrEmpty(value))
            {
                return Activator.CreateInstance(type);
            }
            else
            {
                if (TypeDescriptor.GetConverter(type) is not TypeConverter converter)
                {
                    throw new NotImplementedException("There is no TypeConverter for the specified type.");
                }
                var target = ((IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget)))?.TargetObject as FrameworkElement;
                if (target?.Language.GetEquivalentCulture() is CultureInfo culture)
                    return converter.ConvertFromString(null, culture, value);
                return converter.ConvertFromInvariantString(value);
            }
        }
    }
}

在WPF中的用法:

<Label ... DataContext="{commcore:CreateInstance (local:MyViewModel)}"/>
<Label ... DataContext="{commcore:CreateInstance local:MyViewModel}"/>
<Label ... DataContext="{commcore:CreateInstance (sys:Double)123.456}"/>

最新更新