将包含属性的上下文传递给 TypeConverter [英] Passing a context containing properties to a TypeConverter

查看:30
本文介绍了将包含属性的上下文传递给 TypeConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking for a way of passing additional information to a TypeConverter in order to provide some context for conversions without creating a custom constructor.

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

That extra information passed would be original object (known at compile time as an interface) that contains the property that I am converting. It contains properties of its own like Id that are useful for lookups to convert related information.

我查看了 ITypeDescriptorContext 但我还没有找到如何实现该接口的明确示例.我也不相信这是我需要的工具.

I've had a look at the documentation for ITypeDescriptorContext but I haven't found a clear-cut example of how to implement that interface. I'm also not convinced it's the tool I need.

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

At the moment, in my code I'm calling:

// For each writeable property in my output class.

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

propertyInfo.SetValue(output, converted, null);

我想做的是类似的事情.

What I'd like to do is something like.

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

我希望能够使用重载之一来做我需要的事情,以便任何自定义转换器都可以从 TypeConverter 继承而不是具有自定义构造函数的基类,因为那样会使使用依赖注入更轻松,并使用 DependencyResolver.Current.GetService(type) 从 MVC 初始化我的转换器.

I'd like to be able to use one of the overloads to do what I need so that any custom converters can inherit from TypeConverter rather than a base class with a custom constructor as that would make life easier with dependency injection and use DependencyResolver.Current.GetService(type) from MVC to initialise my converter.

有什么想法吗?

推荐答案

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

The method you want to use is clearly this overload: TypeConverter.ConvertFrom Method (ITypeDescriptorContext, CultureInfo, Object)

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

It will allow you to pass a pretty generic context. The Instance property represents the object instance you're working on, and the PropertyDescriptor property represents the property definition of the property value being converted.

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

For example, the Winforms property grid does exactly that.

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

So, you'll have to provide your own context. Here is a sample one:

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 兼容,如属性网格之一,尽管在现实生活场景中,您必须检查上下文是否为空):

So, let's consider a custom converter, as you see it can grab the existing object's property value using one line of code (note this code is compatible with standard existing ITypeDescriptorContext like the property grid one although in real life scenarios, you must check the context for nullity):

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
        ...
    }
}

现在,如果您修改了这个自定义对象:

Now, if you have this custom object being modified:

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

    public string MySampleProp { get; set; }
}

您可以这样调用转换器:

You can call the converter like this:

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

这篇关于将包含属性的上下文传递给 TypeConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆