Adding to custom collection property in designer

B

Bob Dankert

I have a custom control (inheriting from ListBox) which has a collection as
a property. This collection implements IList (and ICollection, IEnumerator)
and has the DesignerSerializationVisibility set to Content. The collection
consists of a custom class I created, which I also created a typeconverter
so I can use the Visual Studio designer to add items to my collection. When
I try to add items to my collection, I get an error that the constructor can
not be found.

I tried to use this code without the typeconverter and I had the problem
when I added items to my collection, the code would not be created by
designer in VS and therefore they would never be added.

I would appreciate any suggestions

My code for the collection property of the control is here:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyControls.MyListBoxColumnCollection Columns
{
get
{
return this.columns;
}
set
{
this.columns = value;
}
}

The code for the Column item is here (I am omiting the code for the
columncollection as this is very basic):

using System;
using System.Globalization;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
namespace MyControls
{
/// <summary>
/// Summary description for MyListBoxColumn.
/// </summary>
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
private int width;
public MyListBoxColumn(int width)
{
this.width = width;
}
public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}
internal class MyListBoxColumnConverter : 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,CultureInfo
culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
MyListBoxColumn col = (MyListBoxColumn)value;
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, new object[] {col.Width});
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
return ConvertTo(context, culture, value, destinationType);
}
}
}

Thanks

Bob Dankert
 
C

Claes Bergefall

The collection editor calls the public empty constructor
when you press the Add button. Since you don't have
such a constructor you'll get an error. That gives you
two options:

1. Provide a public empty constructor
2. Inherit CollectionEditor and override the
CreateInstance method. Add the Editor
attribute to your collection property
(i.e. Columns) to use your inherited editor


I noticed that the collection property (i.e. Columns)
is read-write. Are you sure you want that (usually
such properties are read-only)?

/claes


Bob Dankert said:
I have a custom control (inheriting from ListBox) which has a collection as
a property. This collection implements IList (and ICollection, IEnumerator)
and has the DesignerSerializationVisibility set to Content. The collection
consists of a custom class I created, which I also created a typeconverter
so I can use the Visual Studio designer to add items to my collection. When
I try to add items to my collection, I get an error that the constructor can
not be found.

I tried to use this code without the typeconverter and I had the problem
when I added items to my collection, the code would not be created by
designer in VS and therefore they would never be added.

I would appreciate any suggestions

My code for the collection property of the control is here:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyControls.MyListBoxColumnCollection Columns
{
get
{
return this.columns;
}
set
{
this.columns = value;
}
}

The code for the Column item is here (I am omiting the code for the
columncollection as this is very basic):

using System;
using System.Globalization;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
namespace MyControls
{
/// <summary>
/// Summary description for MyListBoxColumn.
/// </summary>
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
private int width;
public MyListBoxColumn(int width)
{
this.width = width;
}
public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}
internal class MyListBoxColumnConverter : 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,CultureInfo
culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
MyListBoxColumn col = (MyListBoxColumn)value;
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, new object[] {col.Width});
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
return ConvertTo(context, culture, value, destinationType);
}
}
}

Thanks

Bob Dankert
 
B

Bob Dankert

I made the suggested change to provide an empty parameterless constructor,
and now when I try to add a column I get an unhandles
System.StackOverflowException and Visual Studio immediately terminates.

Any other ideas?

Bob

Claes Bergefall said:
The collection editor calls the public empty constructor
when you press the Add button. Since you don't have
such a constructor you'll get an error. That gives you
two options:

1. Provide a public empty constructor
2. Inherit CollectionEditor and override the
CreateInstance method. Add the Editor
attribute to your collection property
(i.e. Columns) to use your inherited editor


I noticed that the collection property (i.e. Columns)
is read-write. Are you sure you want that (usually
such properties are read-only)?

/claes


Bob Dankert said:
I have a custom control (inheriting from ListBox) which has a collection as
a property. This collection implements IList (and ICollection, IEnumerator)
and has the DesignerSerializationVisibility set to Content. The collection
consists of a custom class I created, which I also created a
typeconverter
so I can use the Visual Studio designer to add items to my collection. When
I try to add items to my collection, I get an error that the constructor can
not be found.

I tried to use this code without the typeconverter and I had the problem
when I added items to my collection, the code would not be created by
designer in VS and therefore they would never be added.

I would appreciate any suggestions

My code for the collection property of the control is here:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyControls.MyListBoxColumnCollection Columns
{
get
{
return this.columns;
}
set
{
this.columns = value;
}
}

The code for the Column item is here (I am omiting the code for the
columncollection as this is very basic):

using System;
using System.Globalization;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
namespace MyControls
{
/// <summary>
/// Summary description for MyListBoxColumn.
/// </summary>
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
private int width;
public MyListBoxColumn(int width)
{
this.width = width;
}
public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}
internal class MyListBoxColumnConverter : 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,CultureInfo
culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
MyListBoxColumn col = (MyListBoxColumn)value;
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, new object[] {col.Width});
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
return ConvertTo(context, culture, value, destinationType);
}
}
}

Thanks

Bob Dankert
 
C

Claes Bergefall

That should work. What does your new constructor look like?
Could you post the rest of the (relevant) code?

/claes


Bob Dankert said:
I made the suggested change to provide an empty parameterless constructor,
and now when I try to add a column I get an unhandles
System.StackOverflowException and Visual Studio immediately terminates.

Any other ideas?

Bob

Claes Bergefall said:
The collection editor calls the public empty constructor
when you press the Add button. Since you don't have
such a constructor you'll get an error. That gives you
two options:

1. Provide a public empty constructor
2. Inherit CollectionEditor and override the
CreateInstance method. Add the Editor
attribute to your collection property
(i.e. Columns) to use your inherited editor


I noticed that the collection property (i.e. Columns)
is read-write. Are you sure you want that (usually
such properties are read-only)?

/claes


Bob Dankert said:
I have a custom control (inheriting from ListBox) which has a
collection
as
a property. This collection implements IList (and ICollection, IEnumerator)
and has the DesignerSerializationVisibility set to Content. The collection
consists of a custom class I created, which I also created a
typeconverter
so I can use the Visual Studio designer to add items to my collection. When
I try to add items to my collection, I get an error that the
constructor
can
not be found.

I tried to use this code without the typeconverter and I had the problem
when I added items to my collection, the code would not be created by
designer in VS and therefore they would never be added.

I would appreciate any suggestions

My code for the collection property of the control is here:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyControls.MyListBoxColumnCollection Columns
{
get
{
return this.columns;
}
set
{
this.columns = value;
}
}

The code for the Column item is here (I am omiting the code for the
columncollection as this is very basic):

using System;
using System.Globalization;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
namespace MyControls
{
/// <summary>
/// Summary description for MyListBoxColumn.
/// </summary>
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
private int width;
public MyListBoxColumn(int width)
{
this.width = width;
}
public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}
internal class MyListBoxColumnConverter : 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,CultureInfo
culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
MyListBoxColumn col = (MyListBoxColumn)value;
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, new object[] {col.Width});
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
return ConvertTo(context, culture, value, destinationType);
}
}
}

Thanks

Bob Dankert
 
J

Jeffrey Tan[MSFT]

Hi Bob,

Based on my understanding, you want to add custom design-time editor for
Collection property.

I have writen a sample project, which works well:
public class UserControl1 : System.Windows.Forms.UserControl
{
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
public MyListBoxColumn()
{
}

private int width=0;
public MyListBoxColumn(int width)
{
this.width = width;
}

public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}

public class MyListBoxColumnConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,Type
destinationType)
{
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)
{
MyListBoxColumn col = (MyListBoxColumn)value;
if (destinationType == typeof(InstanceDescriptor))
{
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new
Type[] {});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, null);
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
if(destinationType==typeof(string))
{
return "MyListBoxColumn"+col.Width.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

MyListBoxColumnCollection columns=null;

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyListBoxColumnCollection Columns
{
get
{
if(columns==null)
{
columns=new MyListBoxColumnCollection();
}
return this.columns;
}
set
{
this.columns = value;
}
}

[TypeConverter(typeof(MyListBoxColumnCollectionConverter))]
public class MyListBoxColumnCollection: CollectionBase
{
public MyListBoxColumn this[int index]
{
get
{
return List[index] as MyListBoxColumn;
}
}

public void Add(MyListBoxColumn item)
{
List.Add(item);
}

public void AddRange(MyListBoxColumn[] items)
{
foreach(MyListBoxColumn item in items)
{
List.Add(item);
}
}
}


internal class MyListBoxColumnCollectionConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,Type
destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}

public override bool CanConvertFrom(ITypeDescriptorContext context, Type
sourceType)
{
if(sourceType==typeof(string))
{
return true;
}
return base.CanConvertFrom (context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value)
{
if(value is string)
{
string str=(string)value;
string[] str_arr=str.Split(new char[]{','});

MyListBoxColumnCollection collection=new MyListBoxColumnCollection();
foreach(string item in str_arr)
{
MyListBoxColumn mlbc=new MyListBoxColumn(int.Parse(item));
collection.Add(mlbc);
}
return collection;
}
return base.ConvertFrom (context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
if (destinationType == typeof(string))
{
MyListBoxColumnCollection collection = (MyListBoxColumnCollection)value;
string str=string.Empty;
foreach(MyListBoxColumn mlbc in collection)
{
str=str+mlbc.Width.ToString()+",";
}
str=str.Substring(0, str.Length-1);
return str;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
==============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Bob,

Also, we may explicitly specify the CollectionEditor to use certain
constructor through inherit the default CollectionEditor, then override
CollectionEditor.CreateInstance method and explicitly call the constructor.
Like this:
public class MyCollectionEditor: CollectionEditor
{
private Type[] types;
public MyCollectionEditor(Type type): base(type)
{
types=new Type[]{typeof(MyListBoxColumn)};
}

protected override Type[] CreateNewItemTypes()
{
return types;
}

protected override object CreateInstance(Type itemType)
{
if(itemType==typeof(MyListBoxColumn))
{
MyListBoxColumn mlbc=new MyListBoxColumn(1);
return mlbc;
}
return base.CreateInstance(itemType);
}
}

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
B

Bob Dankert

Thanks a lot for all your help. I played around with your stuff and
switched around some of my code with yours and was able to determine that my
collection is the problem. If I use all of your code except substitute my
collection in for yours, then the code will no longer work -- it does not
save columns when I add them with the column editor.

I will paste my code below as I am curious what might be wrong with this?

public class MyListBoxColumnCollection : IList
{
private ArrayList myList;
public MyListBoxColumnCollection()
{
myList = new ArrayList();
}
public virtual void AddRange(MyListBoxColumn[] values)
{
foreach (MyListBoxColumn ch in values)
this.myList.Add(ch);
}
#region IList Explicait Members
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyListBoxColumn this[int index]
{
get
{
if (index > this.myList.Count-1)
{
throw new ArgumentOutOfRangeException("MyListBoxColumnCollection.Items
index",index,"Index out of range, please specify a valid value");
}
else
return (MyListBoxColumn)this.myList[index];
}
set
{
if (index > this.myList.Count-1)
{
throw new ArgumentOutOfRangeException("MyListBoxColumnCollection.Items
index",index,"Index out of range, please specify a valid value");
}
else
this.myList[index] = value;
}
}
public void Insert(int index, MyListBoxColumn value)
{
if (index > this.myList.Count-1)
{
throw new ArgumentOutOfRangeException("MyListBoxColumnCollection.Items
index",index,"Index out of range, please specify a valid value");
}
this.myList.Insert(index, value);
}
public void Remove(MyListBoxColumn value)
{
if (this.myList.Contains(value))
this.myList.Remove(value);
}
public bool Contains(MyListBoxColumn value)
{
return this.myList.Contains(value);
}
public int IndexOf(MyListBoxColumn value)
{
return this.myList.IndexOf(value);
}
public int Add(MyListBoxColumn value)
{
return this.myList.Add(value);
}
#endregion
#region ICollection Members
public bool IsSynchronized
{
get
{
return this.myList.IsSynchronized;
}
}
public int Count
{
get
{
return this.myList.Count;
}
}
public void CopyTo(Array array, int index)
{
this.myList.CopyTo(array, index);
}
public object SyncRoot
{
get
{
return this.myList.SyncRoot;
}
}
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return this.myList.GetEnumerator();
}
#endregion
#region IList Members
public bool IsReadOnly
{
get
{
return false;
}
}
object System.Collections.IList.this[int index]
{
get
{
return null;
}
set
{
}
}
void System.Collections.IList.Insert(int index, object value)
{
}
void System.Collections.IList.Remove(object value)
{
}
bool System.Collections.IList.Contains(object value)
{
return false;
}
int System.Collections.IList.IndexOf(object value)
{
return 0;
}
int System.Collections.IList.Add(object value)
{
return 0;
}
public void Clear()
{
this.myList.Clear();
}
public void RemoveAt(int index)
{
if (index > this.myList.Count-1)
{
throw new ArgumentOutOfRangeException("MyListBoxColumnCollection.Items
index",index,"Index out of range, please specify a valid value");
}
this.myList.RemoveAt(index);
}
public bool IsFixedSize
{
get
{
return false;
}
}

#endregion
}


Thanks a ton,

Bob Dankert

"Jeffrey Tan[MSFT]" said:
Hi Bob,

Also, we may explicitly specify the CollectionEditor to use certain
constructor through inherit the default CollectionEditor, then override
CollectionEditor.CreateInstance method and explicitly call the
constructor.
Like this:
public class MyCollectionEditor: CollectionEditor
{
private Type[] types;
public MyCollectionEditor(Type type): base(type)
{
types=new Type[]{typeof(MyListBoxColumn)};
}

protected override Type[] CreateNewItemTypes()
{
return types;
}

protected override object CreateInstance(Type itemType)
{
if(itemType==typeof(MyListBoxColumn))
{
MyListBoxColumn mlbc=new MyListBoxColumn(1);
return mlbc;
}
return base.CreateInstance(itemType);
}
}

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
B

Bob Dankert

Jeffrey,

After doing more testing with this code you provided (the UserControl1
class), I found that while it does add the columns, I have a couple
difficulties:

1. It does not save the widths I assign to the columns. They all go back
to 0 eventually.

2. Instead of showing (Collection) ... in the properties of the designer,
it shows the values of the widths. This works fine, but would be nice to
have it work like the rest of the collections.

3. Is there a way to have the columns automatically name themselves, such
as myListBoxColumn1, myListBoxColumn2, myListBoxColumn3, etc...?

Thanks a ton for all your help,

Bob Dankert
"Jeffrey Tan[MSFT]" said:
Hi Bob,

Based on my understanding, you want to add custom design-time editor for
Collection property.

I have writen a sample project, which works well:
public class UserControl1 : System.Windows.Forms.UserControl
{
[TypeConverter(typeof(MyListBoxColumnConverter))]
public class MyListBoxColumn
{
public MyListBoxColumn()
{
}

private int width=0;
public MyListBoxColumn(int width)
{
this.width = width;
}

public int Width
{
get
{
return this.width;
}
set
{
this.width = value;
}
}
}

public class MyListBoxColumnConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,Type
destinationType)
{
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)
{
MyListBoxColumn col = (MyListBoxColumn)value;
if (destinationType == typeof(InstanceDescriptor))
{
//DockPosition dp = (DockPosition)value;
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new
Type[] {});
//ConstructorInfo ctor = typeof(DockPosition).GetConstructor(new Type[]
{typeof(int), typeof(int)});
return new InstanceDescriptor(ctor, null);
//return new InstanceDescriptor(ctor, new object[] {dp.Left,dp.Top});
}
if(destinationType==typeof(string))
{
return "MyListBoxColumn"+col.Width.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}

MyListBoxColumnCollection columns=null;

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyListBoxColumnCollection Columns
{
get
{
if(columns==null)
{
columns=new MyListBoxColumnCollection();
}
return this.columns;
}
set
{
this.columns = value;
}
}

[TypeConverter(typeof(MyListBoxColumnCollectionConverter))]
public class MyListBoxColumnCollection: CollectionBase
{
public MyListBoxColumn this[int index]
{
get
{
return List[index] as MyListBoxColumn;
}
}

public void Add(MyListBoxColumn item)
{
List.Add(item);
}

public void AddRange(MyListBoxColumn[] items)
{
foreach(MyListBoxColumn item in items)
{
List.Add(item);
}
}
}


internal class MyListBoxColumnCollectionConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context,Type
destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}

public override bool CanConvertFrom(ITypeDescriptorContext context, Type
sourceType)
{
if(sourceType==typeof(string))
{
return true;
}
return base.CanConvertFrom (context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value)
{
if(value is string)
{
string str=(string)value;
string[] str_arr=str.Split(new char[]{','});

MyListBoxColumnCollection collection=new MyListBoxColumnCollection();
foreach(string item in str_arr)
{
MyListBoxColumn mlbc=new MyListBoxColumn(int.Parse(item));
collection.Add(mlbc);
}
return collection;
}
return base.ConvertFrom (context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
if (destinationType == typeof(string))
{
MyListBoxColumnCollection collection = (MyListBoxColumnCollection)value;
string str=string.Empty;
foreach(MyListBoxColumn mlbc in collection)
{
str=str+mlbc.Width.ToString()+",";
}
str=str.Substring(0, str.Length-1);
return str;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
==============================================================
Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
B

Bob Dankert

Ok, I'm sorry for all of the erradic replies, but here is another problem I
ran into. When I try to work with the CollectionEditor, I keep getting an
error that it doesnt belong in the System.ComponentModem.Design namespace.

C:\Programming\Projects\lbcoltest\lbcoltest\lbedit.cs(9): The type or
namespace name 'CollectionEditor' does not exist in the class or namespace
'System.ComponentModel.Design' (are you missing an assembly reference?)

I'm not really sure what is causing this?

Bob Dankert
 
J

Jeffrey Tan[MSFT]

Hi Bob,

This is because System.ComponentModel.Design.CollectionEditor is not
included in default assembly in VS.NET IDE, we should add System.Design.dll
into application as reference. Then we should have no problem using this
class.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
B

Bob Dankert

Jeffrey,

Thanks a ton for the sample file and all of your help. I have finally
figured everything out and tweaked it all to work perfectly with my
projects. I appreciate your help!

Bob Dankert

"Jeffrey Tan[MSFT]" said:
Hi Bob,

Thanks very much for your feedback.

Yes, these can all be done. I will show you one by one.

#1, this is what InstanceDescriptor does. We should provide a
TypeConverter
for Column item(MyListBoxColumn class), override its ConvertTo method,
return MyListBoxColumn's overloading parameterized constructor. Like this:
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
MyListBoxColumn col = (MyListBoxColumn)value;
if (destinationType == typeof(InstanceDescriptor))
{
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
return new InstanceDescriptor(ctor, new object[]{col.Width});
}
}
After providing this, .Net winform code generator will use this
constructor
to persist the collection editor setting in code file.

#2, This is controlled through the collection property's typeconverter, we
may override ConvertTo method, just return "(Collection)", like this:
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
if (destinationType == typeof(string))
{
return "(Collection)";
}
return base.ConvertTo(context, culture, value, destinationType);
}

#3, this name is controlled by Column item(MyListBoxColumn class)'s
TypeConverter. We may override it ConvertTo method, just return the
customized string representation, Like this:
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value, Type
destinationType)
{
MyListBoxColumn col = (MyListBoxColumn)value;
if (destinationType == typeof(InstanceDescriptor))
{
ConstructorInfo ctor = typeof(MyListBoxColumn).GetConstructor(new Type[]
{typeof(int)});
return new InstanceDescriptor(ctor, new object[]{col.Width});
}
if(destinationType==typeof(string))
{
return "my custom item name: "+col.Width.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}

If we want the representation number to increase, we may increase it in
CollectionEditor's CreateInstance method:
private int item_index=0;
protected override object CreateInstance(Type itemType)
{
if(itemType==typeof(MyListBoxColumn))
{
MyListBoxColumn mlbc=new MyListBoxColumn(item_index);
item_index++;
return mlbc;
}
return base.CreateInstance(itemType);
}

I have writen a fully sample for your requirment, and I will attach it in
this reply.
==============================================================
Please apply my suggestion above and let me know if it helps resolve your
problem.

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
B

Bob Dankert

Jeffrey,

I noticed this over the weekend, unfortunately I was getting rather
frusterated with other stuff and not thinking very logically.

Bob Dankert
 
J

Jeffrey Tan[MSFT]

Hi Bob,

You are welcome!! If you need further help, please feel free to tell me, I
will work with you. Thanks

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 

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