【问题标题】:Passing a context containing properties to a TypeConverter将包含属性的上下文传递给 TypeConverter
【发布时间】:2015-04-30 05:11:16
【问题描述】:

我正在寻找一种将附加信息传递给TypeConverter 的方法,以便在不创建自定义构造函数的情况下为转换提供一些上下文。

传递的额外信息将是包含我正在转换的属性的原始对象(在编译时称为接口)。它包含自己的属性,例如 Id,对于查找以转换相关信息很有用。

我查看了ITypeDescriptorContext 的文档,但我还没有找到一个明确的示例来说明如何实现该接口。我也不相信这是我需要的工具。

目前,在我调用的代码中:

// For each writeable property in my output class.

// If property has TypeConverterAttribute
var converted = converter.ConvertFrom(propertyFromOriginalObject)

propertyInfo.SetValue(output, converted, null);

我想做的是这样的。

// Original object is an interface at compile time.
var mayNewValue = converter.ConvertFrom(originalObject, propertyFromOriginalObject)

我希望能够使用其中一个重载来执行我需要的操作,以便任何自定义转换器都可以从 TypeConverter 继承,而不是从具有自定义构造函数的基类继承,因为这将使依赖注入的生活更轻松并使用 MVC 中的 DependencyResolver.Current.GetService(type) 来初始化我的转换器。

有什么想法吗?

【问题讨论】:

  • 您能否解释一下您所说的“附加上下文”是什么意思?
  • 别担心,我已经添加了一点来描述额外的上下文。
  • 谁投了反对票,愿意解释一下吗?
  • 我们都想要更多的背景信息 - 更多的是关于你想做什么而不是如何你想这样做。
  • 标题和问题非常明确。

标签: c# type-conversion typeconverter typedescriptor icustomtypedescriptor


【解决方案1】:

你要使用的方法显然就是这个重载:TypeConverter.ConvertFrom Method (ITypeDescriptorContext, CultureInfo, Object)

它将允许您传递一个非常通用的上下文。 Instance 属性表示您正在处理的对象实例,PropertyDescriptor 属性表示正在转换的属性值的属性定义。

例如,Winforms 属性网格就是这样做的。

因此,您必须提供自己的上下文。这是一个示例:

public class MyContext : ITypeDescriptorContext
{
    public MyContext(object instance, string propertyName)
    {
        Instance = instance;
        PropertyDescriptor = TypeDescriptor.GetProperties(instance)[propertyName];
    }

    public object Instance { get; private set; }
    public PropertyDescriptor PropertyDescriptor { get; private set; }
    public IContainer Container { get; private set; }

    public void OnComponentChanged()
    {
    }

    public bool OnComponentChanging()
    {
        return true;
    }

    public object GetService(Type serviceType)
    {
        return null;
    }
}

所以,让我们考虑一个自定义转换器,如您所见,它可以使用一行代码获取现有对象的属性值(请注意,此代码与标准现有 ITypeDescriptorContext 兼容,例如属性网格之一,尽管在现实生活场景中,您必须检查上下文是否为空):

public class MyTypeConverter : TypeConverter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        // get existing value
        object existingPropertyValue = context.PropertyDescriptor.GetValue(context.Instance);

        // do something useful here
        ...
    }
}

现在,如果您要修改此自定义对象:

public class MySampleObject
{
    public MySampleObject()
    {
        MySampleProp = "hello world";
    }

    public string MySampleProp { get; set; }
}

你可以这样调用转换器:

MyTypeConverter tc = new MyTypeConverter();
object newValue = tc.ConvertFrom(new MyContext(new MySampleObject(), "MySampleProp"), null, "whatever");

【讨论】:

  • 完美!是的,这就是我在自定义转换器中使用的重载。是ITypeDescriptorContext 的实现给我带来了麻烦,我从来没有真正使用过Winforms,主要是网络东西。当我被允许时会增加赏金。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 2016-01-26
  • 2021-11-21
  • 2013-08-23
  • 1970-01-01
  • 2020-06-25
相关资源
最近更新 更多