我想为自定义类型Thickness 实现TypeConverter。我查看了微软发布的类型转换器,如SizeConverter。
当我键入一个字符串或更改我的厚度属性上的一个属性时,设计器会使用它,它只是不会将更改保存到“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;
}
}
我唯一能想到的是转换器是否必须与使用它的设计器代码位于单独的程序集中?