. Topicala Page Index Token

A Journal about the experiences I have developing little applications in C#, Perl, Html and Javascript and talking about things new things that I use. Always Geeky; Always Nerdy; Always poor Grammer!

I am a Software Analyst Developer working in Southport, England but living in Liverpool. I develop mainly in C# and ASP.Net. I have been developing comercial software for several years now. I maintain this site (hosted at SwitchMedia UK) as a way of exploring new technologies (such as AJAX) and just generally talking about techie geek issues. This site is developed through a host of Perl scripts and a liberal use of Javascript. I enjoy experimenting with new technologies and anything that I make I host here.

Quick Search

Web www.kinlan.co.uk

Saturday, October 14, 2006

Solution to my "Problem with List<T> and TypeConverter" Problem

I had a major problem with type converters the other week (see Problem with List <T> and TypeConverter), I could never get them to work as I wanted. 

I had a Generic list that held a list of objects of type T, simple enough.  However when I came to try and use the typeconverter in a component on an XNA Game form or a Windows form they would not work, as expected, additionally the Visual Studio Designer would not create the code for the properties that.

All I wanted was for the code to be created by the designer to look like:

LayerList.Add(new Backgound("c:\\test.bmp"));


The type converter I was creating would take a simple string from the Visual Studio Designer, and apply it to the default constructor which would in turn populate the associated member variable and public property.  The rest of the properties did not need to be designed. 


My type converter was getting complex for such a simple task, it was overriding:



  • CreateInstance
  • GetCreateInstanceSupported
  • CanConvertFrom
  • CanConvertTo
  • ConvertTo
  • ConvertFrom
  • GetProperties
  • GetPropertiesSupported

I really didn't believe that I needed all this complexity, but all the examples I had seen on the Internet were quite complex.  My typeconverter was getting still more complex, I was also attaching a debugger to the Visual Studio IDE and debugging the type converters as they were getting used in my project, just so that I could see what was happening.


In the end I reverted to the best motto I have ever heard, KISS, keep it simple stupid!


I thought that I don't need to be able to edit all the properties on my control from the designer in one string, especially because if I add more complexity to the control it would be hard for developers to use the property designer.  It just didn't make sense to have the designer require a formatted string such as {"C:\test.bmp", 10, 10} to create an object on the form, especially when the designer supports expandable object property editors, which make more sense to use.


Therefore, I thought that I should try a simple override of CanConvertTo and ConvertTo and see what happens.


public class LayerConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,
Type destType)
{
if (destType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destType);
}

public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value, Type destType)
{
if (destType == typeof(InstanceDescriptor))
{
ConstructorInfo ci
=
typeof(Layer).GetConstructor(
System.Type.EmptyTypes);
return new InstanceDescriptor(ci, null, false);
}
return base.ConvertTo(context, culture, value, destType);
}
}

The above code was all that I needed for the designer to correctly serialize the object in the List of types and all the properties.


For instance now, if I added a list of two elements of type Layer to the list, each of the list has a couple of properties on, the code that Visual Studio Produces is:



bg1.FileName = "Media\\cloud.dds";
bg1.LayerDepth
= 0.1F;
bg1.Offset
= new Microsoft.Xna.Framework.Vector2(150F, 100F);
bg1.TileX
= true;
bg1.TileY
= false;

bg2.FileName
= "Media\\cloud.dds";
bg2.LayerDepth
= 0.5F;
bg2.Offset
= new Microsoft.Xna.Framework.Vector2(0F, 0F);
bg2.TileX
= true;
bg2.TileY
= false;

this.component.Backgrounds.Add(bg1);
this.component.Backgrounds.Add(bg2);


tags: , , , , ,

Comments: [Add New]