Serializing Collections to Code

M

Mark Olbert

I'm trying to get a CollectionBase property to serialize properly into the IntializeComponent()
call.

My understanding is that I have to:

1) implement a TypeConverter that can return an InstanceDescriptor that describes how to create the
objects that are in the collection;

2) mark the property as being "content" serializable, and using the custom TypeConverter

3) perhaps also include the Reset<myprop> and ShouldSerialize<myprop> methods as well

I've done all this, and the blasted thing still doesn't work:

the component property stuff:

[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
TypeConverter(typeof(SelectCmdConverter)),
]
public SelectCmdList SelectCmds
{
get
{
if( selectCmds == null )
selectCmds = new SelectCmdList();
return selectCmds;
}
}

// I use this because lazy instantiation makes setting the property from the Designer a pain in the
// butt
internal void SetSelectCmds( SelectCmdList aList )
{
selectCmds = aList;
}

private void ResetSelectCmds()
{
selectCmds = null;
}

private bool ShouldSerializeSelectCmds()
{
// obviously overkill
return true;
}

The custom TypeConverter (translated from a VB.NET Dr GUI example I found): NOTE -- none of these
methods ever get called

public class SelectCmdConverter : TypeConverter
{
public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType )
{
if( destinationType == typeof(InstanceDescriptor) )
return true;

return base.CanConvertTo(context, destinationType);
}

public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo
culture, object value, Type destinationType )
{
if( destinationType == typeof(InstanceDescriptor) )
{
SelectCmd theCmd = (SelectCmd) value;

ConstructorInfo cmdCtor = typeof(SelectCmd).GetConstructor(new Type[] {
typeof(string), typeof(string) });
string[] argList = new string[] { theCmd.Table, theCmd.SelectCommand };

return new InstanceDescriptor(cmdCtor, argList);
}

return base.ConvertTo (context, culture, value, destinationType);
}
}

An excerpt from my custom componentdesigner, where I try to make darn sure someone :) knows the
SelectCmdList has changed:

IComponentChangeService chgSvc = (IComponentChangeService)
Component.Site.GetService(typeof(IComponentChangeService));

PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(Component);
SqlDataPackage thePkg = (SqlDataPackage) Component;
chgSvc.OnComponentChanging(Component, properties["SelectCmds"]);
thePkg.SetSelectCmds(selectCmds);
chgSvc.OnComponentChanged(Component, properties["SelectCmds"], thePkg.SelectCmds, selectCmds);

I can see the ShouldSerialize... method get called in the debugger, and the .cs file where my
component is "sited" gets marked as changed (i.e., the IDE rewrote the InitializeComponent()
method), but there are no references to the SelectCmdList property being initialized!

Any tips or suggestions would be MOST appreciated.

- Mark
 
M

Mark Olbert

Okay, I'm a nitwit: the problem was that I applied the SelectCmdConverter TypeConverter attribute
to the >>SelectCmdList<<, not the SelectCmd class definition itself.

Fixing that resulted in the serialization working correctly.

- Mark
 

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