I'm new to the design time world, so please forgive me if this is a
newbie question.
My control has a property called Model that is a Component. I moved a
bunch of functionality and properties from my control to the Model
because I want to be able to share one Model between multiple controls.
In the PropertyGrid, what I want to see is the property Model that
expands into the various sub-properties, allowing the user to change
the sub-properties. Visual Studio should then serialize the Model
properties if they are not the default values.
I also want to be able to create a stand-alone Model component, add it
to a Form, manipulate it independently of any control, and then assign
it to the control, or, if I don't assign a stand-alone Model component,
have the Designer construct one and assign it to the Model property of
my Control.
It's sort of working, but I have two problems.
1. The Designer will only serialize a new Model as a constructor call,
like this:
this.myListView.Model = new Model("Active", false, false,
SortOrder.None, new string[0]);
This means that I have to have a Model constructor just for the
Designer's use. I would really have preferred syntax like this:
this.myListView.Model = new Model();
this.myListView.Model.ActiveInactiveProperty = "Active";
this.myListView.Model.ReadOnly = false;
this.myListView.Model.MultiSelect = false;
this.myListView.Model.SortMembers = new string[0];
this.myListView.Model.Sorting = SortOrder.None;
but despite my efforts I can't convince the Designer that the
constructor call alone isn't sufficient to initialize the object.
2. I can create a stand-alone Model and set its fields, but the string
next to Model in the PropertyGrid isn't editable, and the PropertyGrid
doesn't give me a drop-down from which to pick the Model, even though
there are ListViewModel component objects defined in the Form, and the
Designer knows about them. I can tweak the code and the Designer
understands what's going on, but I can't get it to offer me a choice.
I _don't_ want what almost every example on PropertyGrid shows: a way
for the user to type in a string and create a Model from the string. In
my case there is no string representation that makes any sense. I _do_
want the user to be able to choose from any Model components added to
the form, or to indicate that they want one constructed for them "on
the fly" (see point #1).
Here is my ExpandableObjectConverter:
public class ListViewModelConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,
Type destinationType)
{
// The model can be converted to an InstanceDescriptor
if (destinationType == typeof(InstanceDescriptor))
{
return true;
}
else
{
return base.CanConvertTo (context, destinationType);
}
}
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value, Type destinationType)
{
if (value is ListViewModel)
{
// Convert to InstanceDescriptor
if (destinationType == typeof(InstanceDescriptor))
{
ListViewModel model = (ListViewModel)value;
ConstructorInfo ci = typeof(ListViewModel).GetConstructor(
new Type[] { typeof(string), typeof(bool), typeof(bool),
typeof(string[]), typeof(SortOrder) });
object[] args = new object[] { model.ActiveInactiveProperty,
model.ReadOnly, model.MultiSelect,
model.SortMembers, model.Sorting };
return new InstanceDescriptor(ci, args);
}
}
return base.ConvertTo (context, culture, value, destinationType);
}
}
and here is the Model property from the parent Control:
[Description("The model that determines how list view items are
selected, sorted, and filtered"),
Category("Behavior")]
public ListViewModel Model
{
get { return this.model; }
set
{
UnsubscribeToModelEvents();
this.model = value;
SubscribeToModelEvents();
}
}
The ListViewModel class itself is decorated with
[TypeConverter(typeof(ListVieWModelConverter))]
joeycalisay - 05 May 2005 01:45 GMT
> 1. The Designer will only serialize a new Model as a constructor call,
> like this:
>
> this.myListView.Model = new Model("Active", false, false,
> SortOrder.None, new string[0]);
this is because you have specified on your typeconverter how to serialize
your Model object using an InstanceDescriptor
> This means that I have to have a Model constructor just for the
> Designer's use. I would really have preferred syntax like this:
[quoted text clipped - 5 lines]
> this.myListView.Model.SortMembers = new string[0];
> this.myListView.Model.Sorting = SortOrder.None;
If you want to have this, just have the Model object instantiated as part of
your custom ListView and add a DesignerSerializationVisibility attribute to
it, set it to Content.
> 2. I can create a stand-alone Model and set its fields, but the string
> next to Model in the PropertyGrid isn't editable, and the PropertyGrid
> doesn't give me a drop-down from which to pick the Model, even though
> there are ListViewModel component objects defined in the Form, and the
> Designer knows about them. I can tweak the code and the Designer
> understands what's going on, but I can't get it to offer me a choice.
can you post snippet of your listviewmodel class...

Signature
Joey Calisay
http://spaces.msn.com/members/joeycalisay/