TypeConverter for struct (like System.Drawing.Color)

R

razor

I need help with a TypeConverter for a structure I created. I want the
structure to function like System.Drawing.Color. I have a structure,
and a custom TypeConverter that works well in design time. The
TypeConverter shows a list of strings in the Property panel, and
properly converts it to the correct structure, and renders to the
design environment correctly.

I serialize it as a string attribute (like Color does). However, when
I go to runtime, it crashes with the following error:

Unable to generate code for a value of type 'MyLibrary.MyStruct'. This
error occurred while trying to generate the property value for
MyProperty.

The Color structure serializes to a color name, so I know this must be
possible. Can anyone give me any ideas? My TypeConverter is derived
from TypeConverter, and I have overriden CanConvertTo, ConvertTo,
CanConvertFrom, ConvertFrom, as well as the GetStandardValues
functions.

Here's my code:

[TypeConverter(typeof(MyListConverter))]
public struct MyStruct
{
public string ID;
public string Command;
}

public struct Command
{
private static MyStruct m_MyStruct;

public static MyStruct Simple1
{
get { SetSimple1(); return m_MyStruct; }
}
public static MyStruct Simple2
{
get { SetSimple2(); return m_MyStruct; }
}
public static MyStruct Simple3
{
get { SetSimple3(); return m_MyStruct; }
}

private static void SetSimple1()
{
m_MyStruct.Command = "Simple1";
m_MyStruct.ID = "Simple1";
}
private static void SetSimple2()
{
m_MyStruct.Command = "Simple2";
m_MyStruct.ID = "Simple2";
}
private static void SetSimple3()
{
m_MyStruct.Command = "Simple3";
m_MyStruct.ID = "Simple3";
}
}

public class MyClass : WebControl
{
public MyClass()
{
Label lbl = new Label();
lbl.Text = "TEST";
this.Controls.Add(lbl);
}

private static MyStruct m_MyStruct;

[Category("Misc"),
PersistenceMode(PersistenceMode.Attribute),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),

NotifyParentProperty(true)]
public MyStruct MyProperty
{
get { return m_MyStruct; }
set
{
if (value.GetType() == typeof(MyStruct))
{
m_MyStruct = value;
}
}
}
}

public class MyListConverter : TypeConverter
{
private ArrayList m_aryValues;

public MyListConverter()
{
// Initializes the standard values list with defaults.
m_aryValues = new ArrayList(new MyStruct[]
{
MyLibrary.Command.Simple1,
MyLibrary.Command.Simple2,
MyLibrary.Command.Simple3
});
}

// Indicates this converter provides a list of standard values.
public override bool
GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}

public override bool
GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

// Returns a StandardValuesCollection of standard value objects.
public override TypeConverter.StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(m_aryValues);
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
Type sourceType)
{
if (sourceType == typeof(string))
return true;
else
return base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value.GetType() == typeof(string))
{
string s = (string) value;

for (int i = 0; i < m_aryValues.Count; i++)
{
MyStruct myStruct = (MyStruct)m_aryValues;
if (s.Equals(myStruct.ID))
return myStruct;
}
}

return base.ConvertFrom(context, culture, value);
}

public override bool CanConvertTo(ITypeDescriptorContext context,
Type
destinationType)
{
if (destinationType == typeof(string))
return true;

return base.CanConvertTo(context, destinationType);
}

public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destType)
{
if (destType == typeof(string))
{
if (value is MyStruct)
{
MyStruct myStruct = (MyStruct)value;

return myStruct.ID;
}
}
return base.ConvertTo(context, culture, value, destType);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top