You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义TypeConverter的ConvertTo方法未对char属性触发调用

问题:自定义Char类型转换器的ConvertTo方法未触发

我有一个类包含char类型属性,用于通信协议,可能存储不可打印字符。依赖默认CharConverter时,不可打印字符无法在属性表单中显示或编辑,因此我编写了自定义TypeConverter,将char转换为Unicode码点的十六进制值展示。

但自定义转换器的CanConvertTo和ConvertTo方法在显示属性值时未被调用:可打印字符仍显示字符本身,不可打印字符无输出,仿佛默认CharConverter仍在生效。奇怪的是,自定义转换器的CanConvertFrom方法(从string转换)能被正常调用并返回true。

相关代码如下:

目标类代码

using System.ComponentModel;

public class SomeClass {

    // ...

    // Property for setting a communications character.
    [
        DisplayName("SomeCharacter"),
        Category("Configuration"),
        Description("Some special communications character, as a hex value."),
        TypeConverter(typeof(CustomCharConverter)),
    ]
    public char SpecialChar {
        get => // ...
        set => // ...
    }
}

自定义转换器代码

public class CustomCharConverter: TypeConverter {

    // ...

    // Overridden CanConvertTo. This is never called.
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {

        // This code never executes.
        if(destinationType == typeof(string) || destinationType == typeof(char)) {
            return true;
        }
        return base.CanConvertTo(context, destinationType);
    }

    // Overridden ConvertTo. This is never called.
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
    Type destinationType) {

        // This code never executes.
        if(destinationType == typeof(string)) {
            return $"0x{((int)((char)value)):X2}"; // Convert char to hex value.
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

解决方案

问题根源在于PropertyGrid对char类型的特殊处理逻辑:它会优先直接调用Char.ToString(),而非触发自定义TypeConverter的ConvertTo方法——除非你的转换器是CharConverter的子类,而非直接继承基础的TypeConverter。

核心修改:继承CharConverter而非TypeConverter

PropertyGrid内部针对char类型有优化,当检测到转换器是CharConverter的子类时,才会完整调用其所有转换逻辑。直接继承TypeConverter会被绕过ConvertTo流程。

修改后的转换器代码:

public class CustomCharConverter : CharConverter // 改为继承CharConverter
{
    // 保留原有的CanConvertFrom实现(处理字符串输入)
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        // 实现字符串转char的逻辑(解析十六进制值)
        if (value is string s)
        {
            // 处理带0x前缀的输入
            if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
                s = s.Substring(2);
            // 解析十六进制为int后转char
            if (int.TryParse(s, System.Globalization.NumberStyles.HexNumber, culture, out int code))
                return (char)code;
        }
        return base.ConvertFrom(context, culture, value);
    }

    // 重写CanConvertTo,明确支持转string
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(string))
            return true;
        return base.CanConvertTo(context, destinationType);
    }

    // 重写ConvertTo,将char转为十六进制字符串
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is char c)
        {
            return $"0x{(int)c:X2}";
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

额外说明

  • 继承CharConverter后,PropertyGrid会正确触发你的ConvertTo逻辑,无论字符是否可打印
  • 如果需要支持常用通信控制字符的快速选择,可以额外重写GetStandardValues方法添加标准值列表

内容的提问来源于stack exchange,提问作者FunctionalFolds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:35:21