I want to implement TypeConverter for a custom type, Thickness. I've looked over the microsoft released typeconverters like SizeConverter.
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...
Here is 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; }
}
}
And here is the type converter:
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?
"We continue to support and innovate in Windows Forms runtime," said Microsoft's Igor Velikorossov last month in announcing what's new for WinForms in . NET 6. He's a software engineer on the dev team for the 19-year-old product, a free and open-source graphical (GUI) class library included as a part of .
WinForms won't be deprecated until Win32 is ... which could be quite sometime! WPF on the other hand has few direct dependencies on Win32 so could potentially form the basis of a "fresh start" UI layer on a future version of windows.
In Microsoft Forms, scroll down to the bottom of your page and select All My Forms. On the All forms tab, select New Collection. Provide a name for your collection and select Create. Your new collection will appear as a tile in the first spot of the top row of your forms.
Provides a unified way of converting types of values to other types, as well as for accessing standard values and subproperties.
So, I hope that my investigation was ended succesfully.
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
.
Now you should be able to edit the Thickness
property in the designer UI. The appropriate code will appear in the *.Designer.cs
file.
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.
Good luck.
This works fine for me. Here are the steps I followed:
public Thickness Thickness { get; set; }
If this isn't working for you, you're either doing something else in your project, or there is a difference in our setups. Can you provide details (.NET version, for example)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With