.NET Forum / Windows Forms / Design Time / December 2004
Interesting VS 2003 designer behavior
|
|
Thread rating:  |
LF - 30 Nov 2004 01:24 GMT Hi,
If I have a property that exposes a custom Collection and has a bunch of AddRange overloads, the AddRange call that takes the argument of type that the property exposes HAS to be the last method declared in the collection class after all the other AddRange method declarations. Otherwise VS designer just picks up the last one even if its' type doesn't correspond to the property exposed and compilation errors will occur. This all comes from VS designer generated code. No such problem in beta of VS 2005.
"Jeffrey Tan[MSFT]" - 03 Dec 2004 05:29 GMT Hi LF,
I am not fully understand this issue, which AddRange overloading must be placed in the last of class definition? Can you paste some code snippet for us to reproduce this issue? So that we can understand it better. Thanks
Best regards, Jeffrey Tan Microsoft Online Partner Support
 Signature Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
LF - 05 Dec 2004 19:03 GMT 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); } }
> Hi LF, > [quoted text clipped - 8 lines] > Get Secure! - www.microsoft.com/security > This posting is provided "as is" with no warranties and confers no rights. "Jeffrey Tan[MSFT]" - 06 Dec 2004 02:24 GMT Hi LF,
Thanks very much for your feedback!!
With your posted sample code, I can reproduce your code generation problem.
I think this behavior is expected, when we invoked collectioneditor in propertybrowser, then clicked "Add" button, the collectioneditor will call the first overloading AddRange method, then generate initialize code for the class item in the collection, so invoke the class's typeconverter, which we intercept the "InstanceDescriptor" call, and explicitly return "public Test(string val)" constructor for the request. Then the following code is generated: this.component11.Test.AddRange(new int[] { new TestApp.Test("val")});
For this issue, I am not sure what is the meaning of your overloading "public void AddRange( int[] items )" statement. I think this overloading does not make sense for CollectionBase, because there is no item in the collection of type "int". Can you show me why you have to use "public void AddRange( int[] items )" overloading method? Then I can understand your senario better. ===================================== 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
 Signature Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
LF - 06 Dec 2004 04:36 GMT Let's say I have a certain type: class Data { public Data(int prop1, string prop2, int prot3, ...){} public Data(string) { //lookup data from key } }
I provide an overload for AddRange for convinience: AddRange(Data data) AddRange(string dataKey)
This is not a problem in VS 2005 beta btw. It's not actually first AddRange. For whatever reason in this simple example it only works when it is first in the declaration. Because in my real code, I have to put AddRange(Data) as last one after all the other AddRange overloads. I actually added nunit test to make sure no one misplaces it. In my real code it comes up last in reflection lookup.
> Hi LF, > [quoted text clipped - 28 lines] > Get Secure! - www.microsoft.com/security > This posting is provided "as is" with no warranties and confers no rights. "Jeffrey Tan[MSFT]" - 07 Dec 2004 02:44 GMT Hi LF,
Thanks very much for your feedback!!
Yes, I see that your collection item class has 2 overloading constructor one requires string parameter, another requires int parameter.
But the collection class's AddRange is to add the class item array into the collection, not the class item's constructor parameter array, we should only provide "AddRange(Data [] data)" for the collection class, because the item in the collection is of type "Data".
In the AddRange method, currently for VS.net 2003, it does not know of the class item's constructor parameter, so your way of implementing AddRange is not supported in VS.net 2003. I hope I have explained it clearly.
I am not sure if VS 2005 supports this way of implementing AddRange method, anyway, it is in beta version, and it is not in offical support now. So in current VS.net 2003 version, the only supported way is passing class item array as parameter for AddRange method.
Hope this information makes sense to you. ============================================= 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
 Signature Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
LF - 07 Dec 2004 03:09 GMT I think VS.NET can easily support this, MethodInfo mi = typeof(DataCollection).GetMethod("AddRange", BindingFlags.Instance|BindingFlags.Public, null, new Type[]{typeof(Data[])}, null);
It should not rely on picking just any AddRange that comes first in reflection lookup. I hope VS.NET 2005 does something similar, because it seems to handle this correctly.
> Hi LF, > [quoted text clipped - 32 lines] > Get Secure! - www.microsoft.com/security > This posting is provided "as is" with no warranties and confers no rights. "Jeffrey Tan[MSFT]" - 08 Dec 2004 08:34 GMT Hi LF,
Thanks very much for your feedback!!
I did not confirm that VS.net can not provide such function at design-time. But the currently VS.net 2003 did not support this design-time function. I am not sure if VS2005 release version will support this. But if you still have concern on this issue in VS.net 2003, I think you may feedback your suggestion to: "http://register.microsoft.com/mswish/suggestion.asp" =================================================== 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
 Signature Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
LF - 08 Dec 2004 12:49 GMT Thank you for your responses
> Hi LF, > [quoted text clipped - 17 lines] > Get Secure! - www.microsoft.com/security > This posting is provided "as is" with no warranties and confers no rights. "Jeffrey Tan[MSFT]" - 09 Dec 2004 01:53 GMT You are welcome. If you need further help, please feel free to post!
Best regards, Jeffrey Tan Microsoft Online Partner Support
 Signature Get Secure! - www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|