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