HighTechTalks DotNet Forums  

ExpandableObjectConverter not serializing to code

Dotnet Framework (WinForms DesignTime) microsoft.public.dotnet.framework.windowsforms.designtime


Discuss ExpandableObjectConverter not serializing to code in the Dotnet Framework (WinForms DesignTime) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Bruce Wood
 
Posts: n/a

Default ExpandableObjectConverter not serializing to code - 08-29-2007 , 04:06 PM






I've written a custom ExpandableObjectConverter for one of my
component types, so that I can change the property of one of my
controls and have the changes serialized as a call to the property
type's constructor.

In Visual Studio 2005, I see the nicely formatted string I provided as
text opposite the property ("Model") of my control, and I get the "+"
that allows me to open up the properties within the Model and change
them. However, when I look at the serialized code, it's all there
except the code to new up an object with which to initialize the
property.

When I run VS 2005 under its own debugger, I see VS2005 calling the
methods in my TypeConverter, but no code is emitted.

This worked under VS2003, but fails in VS2005.

Can anyone see what I'm doing wrong?

First, here is the code for the ExpandableObjectConverter. I've
removed the comments and cut down the indenting to make the post more
readable:

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;
}
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo (context, destinationType);
}

public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
ListViewModel model = (ListViewModel)value;

if (model != null)
{
// Convert to InstanceDescriptor
if (destinationType == typeof(InstanceDescriptor))
{
Type[] constructorParameters = new Type[] { typeof(string),
typeof(bool), typeof(bool), typeof(bool), typeof(string[]),
typeof(SortOrder) };
ConstructorInfo ci =
typeof(ListViewModel).GetConstructor(constructorPa rameters);
object[] args = new object[] { model.HighlightProperty,
model.HighlightPropertyValue, model.ReadOnly, model.MultiSelect,
model.SortMembers, model.Sorting };
if (ci == null)
{
StringBuilder paramTypes = new StringBuilder();
foreach (Type pType in constructorParameters)
{
if (paramTypes.Length > 0)
{
paramTypes.Append(", ");
}
paramTypes.Append(pType.ToString());
}
throw new MethodAccessException(String.Format("Could not
get list view model constructor with parameters {0}: did you change
the parameters to the ListViewModel constructor and forget to fix the
ListViewModelConverter.ConvertTo() method?", paramTypes.ToString()));
}
else
{
return new InstanceDescriptor(ci, args);
}
}
if (destinationType == typeof(string))
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}", model.Name);
if (model.ReadOnly)
{
sb.Append("; read-only");
}
if (model.MultiSelect)
{
sb.Append("; multi-select");
}
else
{
sb.Append("; single-select");
}
if (model.HighlightProperty != null &&
model.HighlightProperty.Length > 0)
{
sb.AppendFormat("; highlight when {0} is {1}",
model.HighlightProperty, model.HighlightPropertyValue);
}
if (model.Sorting == SortOrder.None)
{
sb.Append("; unsorted");
}
else
{
sb.AppendFormat("; sort {0} on ({1})",
model.Sorting.ToString().ToLower(), model.SortMembers);
}
return sb.ToString();
}
}
return base.ConvertTo (context, culture, value,
destinationType);
}

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

public override object CreateInstance(ITypeDescriptorContext
context, IDictionary propertyValues)
{
return new
ListViewModel((string)propertyValues["HighlightProperty"],
(bool)propertyValues["HighlightPropertyValue"],
(bool)propertyValues["ReadOnly"], (bool)propertyValues["MultiSelect"],
(string[])propertyValues["SortMembers"],
(SortOrder)propertyValues["Sorting"]);
return base.CreateInstance(context, propertyValues);
}
}

Here is the code for my component:

[TypeConverter(typeof(ListViewModelConverter))]
[TypeConverter(typeof(ListViewModelConverter))]
public class ListViewModel : Component
{
...
public ListViewModel() : this(null, false, false, true, new
string[0], SortOrder.None)
{ }

public ListViewModel(string highlightPropertyName, bool
highlightPropertyValue, bool readOnly, bool multiSelect, string[]
sortPropertyNames, SortOrder sortOrder)
{
this._itemColl = null;
this._checkedItemColl = null;
this._selectedItemColl = null;
this._selectedItem = null;
this._highlightPropertyName = highlightPropertyName;
this._highlightProperty = null;
this._highlightPropertyValue = highlightPropertyValue;
this._highlightDelegate = new
HighlightItemDelegate(HighlightByProperty);
this._read = readOnly;
this._sortMembers =
CompileSortPropertyPathsToSortMembers(sortProperty Names);
this._sortProperties = null;
this._order = sortOrder;
this._sortKeys = new string[0];
this._mustBeChecked = null;
this._multiSelect = multiSelect;
this._sortItems = null;
this._sortItemsKeys = null;
this._name = "";
}
}
...
[DefaultValue(null), NotifyParentProperty(true)]
public string HighlightProperty
{
get { return this._highlightPropertyName; }
set { ... }
}

[DefaultValue(false), NotifyParentProperty(true)]
public bool HighlightPropertyValue
{
get { return this._highlightPropertyValue; }
set { ... }
}

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializat ionVisibility.Hidden)]
public HighlightItemDelegate HighlightMethod
{
get { ... }
set { ... }
}

[NotifyParentProperty(true)]
public string[] SortMembers
{
get { ... }
set { ... }
}

private bool ShouldSerializeSortMembers()
{
return this._sortMembers.Length > 0;
}

[DefaultValue(SortOrder.None), NotifyParentProperty(true)]
public SortOrder Sorting
{
get { return this._order; }
set { SetSortOrder(this._sortMembers, value); }
}

[DefaultValue(true), NotifyParentProperty(true)]
public bool MultiSelect
{
get { return this._multiSelect; }
set { ... }
}

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializat ionVisibility.Hidden)]
public IKeyed SelectedItem
{
get { ... }
set { ... }
}

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializat ionVisibility.Hidden)]
public SelfKeyedCollection SelectedItems
{
get { ... }
set { ... }
}

[DefaultValue(false), NotifyParentProperty(true)]
public bool ReadOnly
{
get { return this._read; }
set { this._read = value; }
}
}

Finally, here is the declaration of the property of my control:

public class ListViewForSelfKeyedCollection :
System.Windows.Forms.UserControl, IHasListViewModel
{
public ListViewForSelfKeyedCollection()
{
this._model = new ListViewModel();
this._ownModel = true;
SubscribeToModelEvents();
this._displayMembers = new string[][] { new string[]
{ "Description" } };
this._highlightFont = new Font(this.Font, FontStyle.Italic);
this._highlightForeColor = this.ForeColor;
this._highlightBackColor = SystemColors.Window;
this._reactingToModel = false;
this._reactingToUser = false;
this._searchable = true;

// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

this._listView.ListViewItemSorter =
this._model.ListViewItemSorter;
}
...

[Category("Behavior"),
TypeConverter(typeof(ListViewModelConverter))]
public ListViewModel Model
{
get { return this._model; }
set
{
if (value == null)
{
throw new ArgumentNullException("value", "Model property
cannot be set to null.");
}
if (this._model != value)
{
if (this.ModelChanging != null)
{
this.ModelChanging(this, System.EventArgs.Empty);
}
UnsubscribeFromModelEvents();
this._model = value;
this._listView.MultiSelect = this._model.MultiSelect;
this._listView.ListViewItemSorter =
this._model.ListViewItemSorter;
SubscribeToModelEvents();
RebuildListViewContents();
if (this.ModelChanged != null)
{
this.ModelChanged(this, System.EventArgs.Empty);
}
if (this.IsHandleCreated)
{
this._model.Name = String.Format("Model for {0}",
this.Name);
}
}
}
}

protected virtual bool ShouldSerializeModel()
{
return true;
}

protected virtual void ResetModel()
{
this._model = new ListViewModel();
}
}


Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.