Custom collection design time support

D

David Keenan

Hi Everyone,

I'm having problems implementing design time support for a
custom collection in a custom web control. I have managed
to get it to display the collection editor and persist the
collection items into the code of my code behind file.

However, the properties box for the collection does not
display (Collection) as it should, it is simply blank.
Also, after having added items, when I go to edit the
collection again it does not populate the collection
editor with items I have already added, even though they
have been written to the code. I'm sure I have probably
missed something simple, possibly a missing Attribute on
one of my classes??? Any help would be appreciated!

Below is the code I am using, it should copy and paste OK
into a new Web Control Library project. It contains my
Custom control class (TestControl), my item class
(MyClass), my custom collection class (MyClassCollection)
and a custom converter for my item class
(MyClassConverter).


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Reflection;
using System.Globalization;
using System.Windows.Forms;
using System.ComponentModel.Design.Serialization;

namespace TestWebControlLibrary
{
[DefaultProperty("TheList")]
[ToolboxData("<{0}:TestControl runat=server></
{0}:TestControl>")]
public class TestControl :
System.Web.UI.WebControls.WebControl
{
private MyClassCollection theList = null;

[DesignerSerializationVisibility
(DesignerSerializationVisibility.Content)]
public MyClassCollection TheList
{
get{return this.theList;}
}

protected override void Render
(HtmlTextWriter output)
{
output.Write("Test");
}
}

[Serializable()]
[ToolboxItem(false)]
[DesignTimeVisible(false)]
[TypeConverter(typeof(MyClassConverter))]
public class MyClass : Component
{
private string text;

public string Text
{
get{return this.text;}
set{this.text = value;}
}

public MyClass()
{
this.text = "";
}

public MyClass(string text)
{
this.text = text;
}
}

public class MyClassCollection :
System.Collections.CollectionBase
{
public MyClass this[int index]
{
get{return (MyClass)(List[index]);}
set{List[index] = (MyClass)value;}
}

public int Add(MyClass myClass)
{
if(!Contains(myClass))
return List.Add(myClass);
return List.Count;
}

public bool Contains(MyClass myClass)
{
return List.Contains(myClass);
}

public int IndexOf(MyClass myClass)
{
return List.IndexOf(myClass);
}

public void Insert(int index, MyClass
myClass)
{
List.Insert(index, myClass);
}

public void Remove(MyClass myClass)
{
List.Remove(myClass);
}

public void CopyTo(MyClass[] array, int
index)
{
List.CopyTo(array, index);
}
}

public class MyClassConverter :
ExpandableObjectConverter
{
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))
{
ConstructorInfo ci = typeof
(MyClass).GetConstructor(new Type[]{typeof(string)});
MyClass item = (MyClass)
value;
return new
InstanceDescriptor(ci, new object[]{item.Text}, true);
}
return base.ConvertTo(context,
culture, value, destinationType);
}
}
}


I'm really stumped on this one and have spent a couple of
days now trying to figure it out.

Please HELP!

Thanks,

Dave
 
T

Teemu Keiski

Hi,

Specify the collection property as follows:

[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
NotifyParentProperty(true)
]
public MyClassCollection TheList
{
get{
if(theList==null)
{
theList=new MyClassCollection();
}
return theList;
}
}


--
Teemu Keiski
MCP, Microsoft MVP (ASP.NET), AspInsiders member
ASP.NET Forum Moderator, AspAlliance Columnist

David Keenan said:
Hi Everyone,

I'm having problems implementing design time support for a
custom collection in a custom web control. I have managed
to get it to display the collection editor and persist the
collection items into the code of my code behind file.

However, the properties box for the collection does not
display (Collection) as it should, it is simply blank.
Also, after having added items, when I go to edit the
collection again it does not populate the collection
editor with items I have already added, even though they
have been written to the code. I'm sure I have probably
missed something simple, possibly a missing Attribute on
one of my classes??? Any help would be appreciated!

Below is the code I am using, it should copy and paste OK
into a new Web Control Library project. It contains my
Custom control class (TestControl), my item class
(MyClass), my custom collection class (MyClassCollection)
and a custom converter for my item class
(MyClassConverter).


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Reflection;
using System.Globalization;
using System.Windows.Forms;
using System.ComponentModel.Design.Serialization;

namespace TestWebControlLibrary
{
[DefaultProperty("TheList")]
[ToolboxData("<{0}:TestControl runat=server></
{0}:TestControl>")]
public class TestControl :
System.Web.UI.WebControls.WebControl
{
private MyClassCollection theList = null;

[DesignerSerializationVisibility
(DesignerSerializationVisibility.Content)]
public MyClassCollection TheList
{
get{return this.theList;}
}

protected override void Render
(HtmlTextWriter output)
{
output.Write("Test");
}
}

[Serializable()]
[ToolboxItem(false)]
[DesignTimeVisible(false)]
[TypeConverter(typeof(MyClassConverter))]
public class MyClass : Component
{
private string text;

public string Text
{
get{return this.text;}
set{this.text = value;}
}

public MyClass()
{
this.text = "";
}

public MyClass(string text)
{
this.text = text;
}
}

public class MyClassCollection :
System.Collections.CollectionBase
{
public MyClass this[int index]
{
get{return (MyClass)(List[index]);}
set{List[index] = (MyClass)value;}
}

public int Add(MyClass myClass)
{
if(!Contains(myClass))
return List.Add(myClass);
return List.Count;
}

public bool Contains(MyClass myClass)
{
return List.Contains(myClass);
}

public int IndexOf(MyClass myClass)
{
return List.IndexOf(myClass);
}

public void Insert(int index, MyClass
myClass)
{
List.Insert(index, myClass);
}

public void Remove(MyClass myClass)
{
List.Remove(myClass);
}

public void CopyTo(MyClass[] array, int
index)
{
List.CopyTo(array, index);
}
}

public class MyClassConverter :
ExpandableObjectConverter
{
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))
{
ConstructorInfo ci = typeof
(MyClass).GetConstructor(new Type[]{typeof(string)});
MyClass item = (MyClass)
value;
return new
InstanceDescriptor(ci, new object[]{item.Text}, true);
}
return base.ConvertTo(context,
culture, value, destinationType);
}
}
}


I'm really stumped on this one and have spent a couple of
days now trying to figure it out.

Please HELP!

Thanks,

Dave
 
D

David Keenan

Thank you very much, I was beginning to tear my hair out
over that! I knew it would be something relatively simple
but couldn't find it anywhere.

Thanks again!

Dave
-----Original Message-----
Hi,

Specify the collection property as follows:

[
DesignerSerializationVisibility (DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
NotifyParentProperty(true)
]
public MyClassCollection TheList
{
get{
if(theList==null)
{
theList=new MyClassCollection();
}
return theList;
}
}


--
Teemu Keiski
MCP, Microsoft MVP (ASP.NET), AspInsiders member
ASP.NET Forum Moderator, AspAlliance Columnist

Hi Everyone,

I'm having problems implementing design time support for a
custom collection in a custom web control. I have managed
to get it to display the collection editor and persist the
collection items into the code of my code behind file.

However, the properties box for the collection does not
display (Collection) as it should, it is simply blank.
Also, after having added items, when I go to edit the
collection again it does not populate the collection
editor with items I have already added, even though they
have been written to the code. I'm sure I have probably
missed something simple, possibly a missing Attribute on
one of my classes??? Any help would be appreciated!

Below is the code I am using, it should copy and paste OK
into a new Web Control Library project. It contains my
Custom control class (TestControl), my item class
(MyClass), my custom collection class (MyClassCollection)
and a custom converter for my item class
(MyClassConverter).


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Reflection;
using System.Globalization;
using System.Windows.Forms;
using System.ComponentModel.Design.Serialization;

namespace TestWebControlLibrary
{
[DefaultProperty("TheList")]
[ToolboxData("<{0}:TestControl runat=server></
{0}:TestControl>")]
public class TestControl :
System.Web.UI.WebControls.WebControl
{
private MyClassCollection theList = null;

[DesignerSerializationVisibility
(DesignerSerializationVisibility.Content)]
public MyClassCollection TheList
{
get{return this.theList;}
}

protected override void Render
(HtmlTextWriter output)
{
output.Write("Test");
}
}

[Serializable()]
[ToolboxItem(false)]
[DesignTimeVisible(false)]
[TypeConverter(typeof(MyClassConverter))]
public class MyClass : Component
{
private string text;

public string Text
{
get{return this.text;}
set{this.text = value;}
}

public MyClass()
{
this.text = "";
}

public MyClass(string text)
{
this.text = text;
}
}

public class MyClassCollection :
System.Collections.CollectionBase
{
public MyClass this[int index]
{
get{return (MyClass)(List[index]);}
set{List[index] = (MyClass)value;}
}

public int Add(MyClass myClass)
{
if(!Contains(myClass))
return List.Add(myClass);
return List.Count;
}

public bool Contains(MyClass myClass)
{
return List.Contains(myClass);
}

public int IndexOf(MyClass myClass)
{
return List.IndexOf(myClass);
}

public void Insert(int index, MyClass
myClass)
{
List.Insert(index, myClass);
}

public void Remove(MyClass myClass)
{
List.Remove(myClass);
}

public void CopyTo(MyClass[] array, int
index)
{
List.CopyTo(array, index);
}
}

public class MyClassConverter :
ExpandableObjectConverter
{
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))
{
ConstructorInfo ci = typeof
(MyClass).GetConstructor(new Type[]{typeof(string)});
MyClass item = (MyClass)
value;
return new
InstanceDescriptor(ci, new object[]{item.Text}, true);
}
return base.ConvertTo(context,
culture, value, destinationType);
}
}
}


I'm really stumped on this one and have spent a couple of
days now trying to figure it out.

Please HELP!

Thanks,

Dave


.
 

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

Members online

No members online now.

Forum statistics

Threads
473,818
Messages
2,569,736
Members
45,709
Latest member
DRISenaida

Latest Threads

Top