Example follows. Note the order of two AddRange methods:
public void AddRange( int[] items )
public void AddRange( Test[] items )
Change them around and everything is fine. For the above order of
declarations we'll get this from VS designer:
this.component11.Test.AddRange(new int[] { new TestApp.Test("val")});
And of course this will not build. I'm not sure anymore what the order of
declarations should be for VS 2003 designer to pick the right signature. I
guess whatever is returned last from Reflection.
public class Component1 : Component
{
public Component1(System.ComponentModel.IContainer container)
{
container.Add(this);
}
public Component1(){}
TestCollection _test = new TestCollection();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
public TestCollection Test
{
get { return _test; }
}
bool ShouldSerializeTest()
{
return true;
}
}
public class TestCollection : CollectionBase
{
public TestCollection()
{
}
public Test this[ int index ]
{
get { return (Test)base.List[ index ]; }
}
public void Add( Test item )
{
base.List.Add( item );
}
public void Remove(int index)
{
base.List.Remove(index);
}
public void Remove(Test item)
{
base.List.Remove(item);
}
public void AddRange( int[] items )
{
}
public void AddRange( Test[] items )
{
}
public int IndexOf( Test item )
{
return base.List.IndexOf( item );
}
public bool Contains(Test item)
{
return base.List.Contains(item);
}
public void Insert( System.Int32 index , Test item)
{
base.List.Insert(index, item);
}
}
[TypeConverter(typeof(TestTypeConverter))]
public class Test
{
public Test(){}
public Test(string val){}
}
internal sealed class TestTypeConverter: 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(value is Test)
{
if(destinationType == typeof(string))
return ((Test)value).ToString();
else if(destinationType == typeof(InstanceDescriptor))
{
ConstructorInfo ci = typeof(Test).GetConstructor(new
Type[]{typeof(string)});
Test test = (Test) value;
return new InstanceDescriptor(ci,new object[]{"val"});
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
[quoted text, click to view] ""Jeffrey Tan[MSFT]"" <v-jetan@online.microsoft.com> wrote in message
news:fB4GgWf1EHA.3512@cpmsftngxa10.phx.gbl...
> Hi LF,
>
> Thanks for your posting!!
>
> After trying your code snippet I have reproduced out this issue.
>
> I suspect that VS.net designer will store the CodeDOM references in
> hashtable, so when generating the reference, it will query the object's
> GetHashCode method. Because you apply the string.GetHashCode logic to the
> Test.GetHashCode method, designer will generate the same reference names
> for the Test items with the same string field.
>
> I think this behavior is by design. I am not sure why you use
> isComplete=false for InstanceDescriptor, your Test class has only one
> field
> "Data", so when use set it in Test's constructor, all the information for
> Test class is complete, isComplete=true for InstanceDescriptor is more
> suitable for this senario. And using isComplete=false for
> InstanceDescriptor will not have such problem in VS.net.
>
> If you have any other concern on this issue, please feel free to tell me.
> 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.
>