I'm making controls for my winform program, and this error happens when saving the test form.
This is the solution structure, the controls library is seperated in 1 project and another is a test project contains a test form.
Solution
├ Test (Test Project)
│ └ Form1
└ WinFormControls (Library Project)
└ ImageButton (UserControl)
The control has a TypeConverter
attached, here is brief code.
To make the question simple, I omit other methods, you can read it from this link
public class StateConverter : ExpandableObjectConverter
{
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if(destinationType == typeof(InstanceDescriptor))
{
var ctor = typeof(State).GetConstructor(new Type[] { typeof(int), typeof(Image) });
if (ctor != null)
{
var state = (State)value;
return new InstanceDescriptor(ctor, new object[] { state.GetData(), state.Image });
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
The error is not always happens here are steps to reproduce:
- Open the solution in VS
- Open the Form1 designer, drag an ImageButton from toolbox
- Make some change in ImageButton.cs (eg. add a space), then rebuild the solution
- Return to the Form1 designer, make some change with NormalState property in the properties window, then save, the error occurs.
- Since then if you make change on the ImageButton and save, the error will show, even if drag another ImageButton from the toolbox, except reopen the VS.
After some debug, I found the error occurs with this line:
var state = (State)value;
At first I guessed the value is null, so I added some log with it:
try {
var state = (State)value;
} catch (Exception ex) {
File.AppendAllText("errorlog.txt", ex.ToString() +
(value == null ? "NULL" : value.GetType().ToString());
}
Finally I got:
System.InvalidCastException: Specified cast is not valid. at WinFormControls.ImageButton.StateConverter.ConvertTo ...... WinFormControls.ImageButton+State
So the value is not null, and the type of value is exactly what I cast to.
Update
Output AssemblyQualifiedName, IsAssignableFrom, is:
value.GetType().AssemblyQualifiedName;
typeof(State).AssemblyQualifiedName;
typeof(State).IsAssignableFrom(value.GetType());
value.GetType().IsAssignableFrom(typeof(State))
value is State
ReferenceEquals(value.GetType(), typeof(State))
Strange result:
WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
WinFormControls.ImageButton+State, WinFormControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
False
False
False
False
Two questions:
- Why the error happens?
- How can I avoid it during developing?