Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Design Time / June 2006

Tip: Looking for answers? Try searching our database.

Object of type 'MyType' cannot be converted to type 'MyType'

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Thomas Pagh - 16 Jun 2006 09:23 GMT
Hi,

I am experiencing some weird problems with Visual Studio 2005's Property
Grid in the designer, whenever I rebuild my assemblies containing my custom
TypeConverters. It seems to me that the Property Grid doesn't reload the
rebuilded assembly.

I have created a class called CornerType with a CornerTypeConverter, the
CornerTypeConverter creates a new instance of CornerType, whenever one of
CornerType values are changed - very simular to System.Windows.Forms.Padding
and System.Windows.Forms.PaddingConverter.

At times the CornerTypeConverter will need to cast an object (of type
CornerType) to CornerType. This works fine right until I build a new version
of the assembly (dll) that contains the CornerType and CornerTypeConverter.
After that I get an castexception, when trying to cast an object (of type
CornerType) to CornerType. It seems, that the object I am casting from is a
different version of CornerType than the CornerType I am trying to cast to.

It is very simple to reproduce:
1. Just make a simple WinForm application (C#), add the code for CornerType
and CornerTypeConverter (posted below), add a UserControl with a CorneType
property and BUILD your solution.
2. Add the UserControl to your Form.
3. In the designer, You can change the value of the CornerType, either by
expanding the property and modify a field, or by entering a string in the
'header'.
The string should be a single number or 4 numbers seperated by a ';' or ','.
4. REBUILD the solution.
5. now if you repeat step 3 you will get various cast exceptions.
When changing the property by entering a string, you will invoke the
ConvertFrom() in the CornerTypeConverter which will throw following
exception:

Object of type 'Oticon.Genie.Forms.CornersType' cannot be converted to type
'Oticon.Genie.Forms.CornersType'.

When changing the property by expanding it, and modifying a field, you will
invoke the CreateInstance() in the CornerTypeConverter which will throw
following exception:

Specified cast is not valid.

6. Now close and reopen Visual Studio, and repeat step 3, now it works fine
again!!!

Included code for CornersType.cs and CornersTypeConverter.cs

CornersType.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace CornerTypeTest
{
   [TypeConverter(typeof(CornersTypeConverter))]
   public struct CornersType
   {
       public const int defaultRadius = 10;
       public const string defaultCornerTypeStr = "10; 10; 10; 10";

       [DefaultValue(defaultRadius)]
       [RefreshProperties(RefreshProperties.All)]
       public int All
       {
           get
           {
               if (topRight == topLeft && bottomLeft == topLeft &&
bottomRight == topLeft)
                   return topLeft;
               return -1;
           }
           set
           {
               topLeft = value; topRight = value; bottomLeft = value;
bottomRight = value;
           }
       }

       private int topLeft;
       [DefaultValue(defaultRadius)]
       [RefreshProperties(RefreshProperties.All)]
       public int TopLeft
       {
           get { return topLeft; }
           set
           {
               topLeft = value;
           }
       }

       private int topRight;
       [DefaultValue(defaultRadius)]
       [RefreshProperties(RefreshProperties.All)]
       public int TopRight
       {
           get { return topRight; }
           set
           {
               topRight = value;
           }
       }

       private int bottomLeft;
       [DefaultValue(defaultRadius)]
       [RefreshProperties(RefreshProperties.All)]
       public int BottomLeft
       {
           get { return bottomLeft; }
           set
           {
               bottomLeft = value;
           }
       }

       private int bottomRight;
       [DefaultValue(defaultRadius)]
       [RefreshProperties(RefreshProperties.All)]
       public int BottomRight
       {
           get { return bottomRight; }
           set
           {
               bottomRight = value;
           }
       }

       //public CornersType()
       //{
       //    this.topLeft = defaultRadius;
       //    this.topRight = defaultRadius;
       //    this.bottomLeft = defaultRadius;
       //    this.bottomRight = defaultRadius;
       //}

       public CornersType(int all)
       {
           this.topLeft = all;
           this.topRight = all;
           this.bottomLeft = all;
           this.bottomRight = all;
       }

       public CornersType(int topLeft, int topRight, int bottomLeft, int
bottomRight)
       {
           this.topLeft = topLeft;
           this.topRight = topRight;
           this.bottomLeft = bottomLeft;
           this.bottomRight = bottomRight;
       }

       public static bool operator ==(CornersType ct1, CornersType ct2)
       {
           return ((ct1.topLeft == ct2.topLeft) && (ct1.topRight ==
ct2.topRight) && (ct1.bottomLeft == ct2.bottomLeft) && (ct1.bottomRight ==
ct2.bottomRight));
       }

       public static bool operator !=(CornersType ct1, CornersType ct2)
       {
           return !(ct1 == ct2);
       }

       public override bool Equals(object obj)
       {
           if (obj is CornersType)
               return (CornersType)obj == this;
           return false;
       }

       public override int GetHashCode()
       {
           return base.GetHashCode();
       }
   }
}

CornersTypeConverter.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;
using System.Drawing;
using System.Collections;
using System.ComponentModel.Design.Serialization;
using System.Windows.Forms;

namespace CornerTypeTest
{
   class CornersTypeConverter : TypeConverter
   {
       public override bool GetPropertiesSupported(ITypeDescriptorContext
context)
       {
           return true;
       }

       public override PropertyDescriptorCollection
GetProperties(ITypeDescriptorContext context, object value, Attribute[]
attributes)
       {
           PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(value, attributes);
           return properties.Sort(new string[] { "All", "TopLeft",
"TopRight", "BottomLeft", "BottomRight" });
       }

       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)
       {
           if (destinationType == typeof(String))
           {
               CornersType corners = (CornersType)value;
               return string.Format("{0}; {1}; {2}; {3}", corners.TopLeft,
corners.TopRight, corners.BottomLeft, corners.BottomRight);
           }
           if (destinationType == typeof(InstanceDescriptor))
           {
               CornersType corners = (CornersType)value;
               if (corners.All != -1)
                   return new
InstanceDescriptor(typeof(CornersType).GetConstructor(new Type[] {
typeof(int) }), new object[] { corners.All });
               return new
InstanceDescriptor(typeof(CornersType).GetConstructor(new Type[] {
typeof(int), typeof(int), typeof(int), typeof(int) }), new object[] {
corners.TopLeft, corners.TopRight, corners.BottomLeft, corners.BottomRight });
           }
           return base.ConvertTo(context, culture, value, 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[] values;
               //first try with ';' as delimiter
               if (((string)value).Contains(";"))
                   values = ((string)value).Split(new char[] { ';' });
               //if no success then try with ',' as delimiter
               else
                   values = ((string)value).Split(new char[] { ',' });
               if (values.Length == 4)
                   return new CornersType(int.Parse(values[0]),
int.Parse(values[1]), int.Parse(values[2]), int.Parse(values[3]));
               else if (values.Length == 1)
                   return new CornersType(int.Parse(values[0]));
           }
           return base.ConvertFrom(context, culture, value);
       }

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

       public override object CreateInstance(ITypeDescriptorContext
context, IDictionary propertyValues)
       {
           if (context == null)
           {
               throw new ArgumentNullException("context");
           }
           if (propertyValues == null)
           {
               throw new ArgumentNullException("propertyValues");
           }

           CornersType oldCorners =
(CornersType)context.PropertyDescriptor.GetValue(context.Instance);
           int newAll = (int)propertyValues["All"];
           if (oldCorners.All != newAll)
           {
               return new CornersType(newAll);
           }
   
           return new CornersType((int)propertyValues["TopLeft"],
(int)propertyValues["TopRight"], (int)propertyValues["BottomLeft"],
(int)propertyValues["BottomRight"]);
       }
   }
}
Thomas Pagh - 21 Jun 2006 21:39 GMT
I found a solution to thr problem myself.
I just needed to change the AssemblyVersion each time I rebuild the assembly
containing the typeconverter.

One way to do this was to change the AssemblyVersion attribute in the
AssemblyI nfo.cs file to 1.0.0.*.

/Thomas Pagh

> Hi,
>
[quoted text clipped - 296 lines]
>             {
>                 return new CornersType(newAll);

Rate this thread:







Free Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.