首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Windows窗体上实现TypeConverter

在Windows窗体上实现TypeConverter
EN

Stack Overflow用户
提问于 2013-11-13 22:13:27
回答 2查看 1.4K关注 0票数 5

我想为一个自定义类型,厚度实现TypeConverter。我看过微软发布的打字机,比如SizeConverter

当我键入一个字符串或更改我的厚度属性上的一个属性时,设计器使用它,它只是不将更改保存到“Designer.cs”。它必须是从类型‘厚度’到'InstanceDescriptor‘的转换,但我发现我的代码没有任何问题.

这是Thickness

代码语言:javascript
复制
[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; }
    }
}

这是类型转换器:

代码语言:javascript
复制
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;
    }
}

我唯一能想到的是转换器必须在一个独立的程序集中,而不是使用它的设计人员代码中吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-17 01:51:13

所以,我希望我的调查能圆满结束。

结果:

这件事很奇怪。VS2008中似乎有一些bug。

要使您的代码像预期的那样工作:

  1. ThicknessConverter重命名为其他东西(例如:Thickness1Converter)。
  2. 通过按Shift+F6构建解决方案。

现在,您应该能够在designer UI中编辑Thickness属性。适当的代码将出现在*.Designer.cs文件中。

在此之后,在某些情况下,可以将其重命名为ThicknessConverter,而不会出现错误。但我没发现规矩抱歉。

如果有些事情不够清楚,请毫不犹豫地问我。

祝好运。

票数 5
EN

Stack Overflow用户

发布于 2013-11-13 22:30:05

这对我来说很好。以下是我遵循的步骤:

  1. 启动VS2010。
  2. 创建一个新的WinForms项目(.NET Framework4客户端配置文件)。
  3. 复制粘贴您的厚度和ThicknessConverter类。
  4. 创建一个新的用户控件UserControl1。
  5. 向用户控件添加属性:public Thickness Thickness { get; set; }
  6. 建造项目。
  7. 打开Form1设计器。
  8. 将UserControl1放在Form1上。
  9. 选择UserControl1。
  10. 编辑厚度属性。
  11. 保存。
  12. 在Form1.Designer.cs中验证厚度是否正确。

如果这不适合您,您要么在项目中做其他的事情,要么在我们的设置上有差异。您能提供详细信息(例如.NET版本)吗?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19965502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档