我想为自定义类型“厚度”实现TypeConverter。我看过像SizeConverter这样的Microsoft发布的typeconverters。

当我输入字符串或更改我的Thickness属性的其中一个属性时,设计器将使用它,只是不会将更改保存到'Designer.cs'。它必须是从“Thickness”类型到“InstanceDescriptor”类型的转换,但是我的代码找不到任何错误...

这是Thickness:

[TypeConverter(typeof(ThicknessConverter))]
public struct Thickness
{
    Double top;
    Double bottom;
    Double right;
    Double left;

    public Thickness(Double uniformLength)
    {
        top = uniformLength;
        bottom = uniformLength;
        right = uniformLength;
        left = uniformLength;
    }

    public Thickness(Double left, Double top, Double right, Double bottom)
    {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
    }
    public Double Top
    {
        get { return top; }
        set { top = value; }
    }
    public Double Bottom
    {
        get { return bottom; }
        set { bottom = value; }
    }
    public Double Right
    {
        get { return right; }
        set { right = value; }
    }
    public Double Left
    {
        get { return left; }
        set { left = value; }
    }
    public Double UniformLength
    {
        get
        {
            if (!IsUniform)
                throw new InvalidOperationException();
            else return top;
        }
        set
        {
            top = value;
            bottom = value;
            right = value;
            bottom = value;
        }
    }
    public Boolean IsUniform
    {
        get { return top == bottom && bottom == right && bottom == left; }
    }
}

这是类型转换器:
public class ThicknessConverter : TypeConverter
{
    public ThicknessConverter()
    {
    }

    public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(String) || destinationType == typeof(InstanceDescriptor);
    }
    public override Object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, Object value, Type destinationType)
    {
        Thickness thickness = (Thickness)value;
        if (destinationType == typeof(String))
        {
            if (thickness.IsUniform)
                return thickness.Right.ToString();
            else return thickness.Left + "," + thickness.Top + "," + thickness.Right + "," + thickness.Bottom;
        }
        else if (destinationType == typeof(InstanceDescriptor))
        {
            if (thickness.IsUniform)
                return new InstanceDescriptor(typeof(Thickness).GetConstructor(new Type[] { typeof(Double) }), new Object[] { thickness.UniformLength });
            else
            {
                ConstructorInfo constructor = typeof(Thickness).GetConstructor(new Type[] { typeof(Double), typeof(Double), typeof(Double), typeof(Double) });
                return new InstanceDescriptor(constructor, new Object[] { thickness.Left, thickness.Top, thickness.Right, thickness.Bottom });
            }
        }
        else return null;
    }
    public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(String);
    }
    public override Object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, Object value)
    {
        if (value is String)
        {
            String stringValue = (String)value;
            if (stringValue.Contains(","))
            {
                String[] stringValues = stringValue.Split(',');
                Double[] values = new Double[stringValues.Length];
                if (values.Length == 4)
                {
                    try
                    {
                        for (Int32 i = 0; i < 4; i++)
                            values[i] = Double.Parse(stringValues[i]);
                    }
                    catch (Exception)
                    {
                        return new Thickness();
                    }
                    return new Thickness(values[0], values[1], values[2], values[3]);
                }
                else return new Thickness();
            }
            else
            {
                try
                {
                    return new Thickness(Double.Parse(stringValue));
                }
                catch (Exception)
                {
                    return new Thickness();
                }
            }
        }
        else return base.ConvertFrom(context, culture, value);
    }
    public override Boolean GetCreateInstanceSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override Object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
    {
        return new Thickness((Double)propertyValues["Left"], (Double)propertyValues["Top"], (Double)propertyValues["Right"], (Double)propertyValues["Bottom"]);
    }

    public override Boolean GetPropertiesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Object value, Attribute[] attributes)
    {
        PropertyDescriptorCollection collection = TypeDescriptor.GetProperties(typeof(Thickness));
        collection = collection.Sort(new String[] { "Left", "Top", "Right", "Bottom" });
        collection.RemoveAt(4);
        collection.RemoveAt(4);
        return collection;
    }
}

我唯一能想到的是,转换器必须与使用该转换器的设计人员代码分开安装在单独的组件中吗?

最佳答案

因此,我希望调查能够成功结束。

结果:
这很奇怪。似乎VS2008中存在一些错误。
为了使您的代码按预期工作:
1.将ThicknessConverter重命名为其他名称(例如:Thickness1Converter)。
2.按Shift+F6构建解决方案。

现在,您应该可以在设计器UI中编辑Thickness属性。相应的代码将出现在*.Designer.cs文件中。

之后,在某些情况下,可以将其重命名为ThicknessConverter而不会出错。但是我找不到规则,对不起。

如果不清楚的地方,请随时问我。

祝你好运。

关于c# - 为Windows窗体实现TypeConverter,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19965502/

10-11 01:30