Windows窗体实现类型转换器 [英] Implementing TypeConverter for Windows Forms

查看:105
本文介绍了Windows窗体实现类型转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要实现的TypeConverter自定义类型,厚度。我看了在微软发布类似的 SizeConverter

I want to implement TypeConverter for a custom type, Thickness. I've looked over the microsoft released typeconverters like SizeConverter.

当我输入一个字符串或更改的属性之一在我的厚度方向性能,设计师的作品吧,它只是不更改保存到Designer.cs。它必须从类型'厚度'到'初始化InstanceDescriptor转换,但我找不到什么毛病我的代码...

When I type a string or change one of the properties on my Thickness property, the designer works with it, it just doesn't save the change to 'Designer.cs'. It has to be the conversion from the type 'Thickness' to 'InstanceDescriptor' but I can't find anything wrong with my code...

下面是厚度

[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;
    }
}



我能想到的唯一的事情做转换器必须在一个单独的组件,比使用它的设计器代码?

The only thing I can think of is does the converter have to be in a seperate assembly than the designer code using it?

推荐答案

所以,我希望我的调查已成功结束。

So, I hope that my investigation was ended succesfully.

结果:结果
这是一些奇怪的事情。它似乎还有在VS2008中的一些bug结果
为了让你的代码按预期工作:结果
1.重命名 ThicknessConverter 的东西其他(例如: Thickness1Converter )。结果
2.建立按解决方案 Shift + F6

The result:
This is something strange. It seems there is some bug in VS2008.
To get your code works as expected:
1. Rename ThicknessConverter to something else (for example: Thickness1Converter).
2. Build the solution by pressing Shift+F6.

现在,你应该能够编辑厚度在设计UI属性。适当的代码将出现在 *。Designer.cs 文件。

Now you should be able to edit the Thickness property in the designer UI. The appropriate code will appear in the *.Designer.cs file.

此后,在某些情况下,有可能没有得到它回到重命名为 ThicknessConverter 一个错误。但我不能发现规则,对不起。

After that, in some circumstances, it is possible to rename it back to the ThicknessConverter without getting an error. But I can't discover the rule, sorry.

如果事情是不够清楚,不要犹豫,问我。

If something isn't clear enough, do not hesitate to ask me.

祝你好运。

这篇关于Windows窗体实现类型转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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