Я создаю элементы управления для моей программы winform, и эта ошибка возникает при сохранении тестовой формы.
Это структура решения, библиотека элементов управления разделена на 1 проект, а другой - тестовый проект, содержащий тестовую форму.
Solution
├ Test (Test Project)
│ └ Form1
└ WinFormControls (Library Project)
└ ImageButton (UserControl)
К элементу управления прикреплено TypeConverter
, вот краткий код.
Чтобы упростить вопрос, я опускаю другие методы, вы можете прочитать его по по этой ссылке
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);
}
}
Ошибка не всегда происходит, вот шаги для воспроизведения:
- Откройте решение в VS
- Откройте дизайнер Form1, перетащите ImageButton из панели инструментов
- Сделайте некоторые изменения в ImageButton.cs (например, добавьте пробел), затем перестройте решение
- Вернитесь к конструктору Form1, внесите некоторые изменения со свойством NormalState в окне свойств, затем сохраните, возникает ошибка.
- С тех пор, если вы внесете изменения в ImageButton и сохраните, ошибка будет отображаться, даже если перетащить другую ImageButton из панели инструментов, за исключением повторного открытия VS.
После некоторой отладки я обнаружил ошибку с этой строкой:
var state = (State)value;
Сначала я догадался, что значение равно нулю, поэтому добавил к нему журнал:
try {
var state = (State)value;
} catch (Exception ex) {
File.AppendAllText("errorlog.txt", ex.ToString() +
(value == null ? "NULL" : value.GetType().ToString());
}
Наконец я получил:
System.InvalidCastException: указанное приведение недействительно. в
WinFormControls.ImageButton.StateConverter.ConvertTo ......
WinFormControls.ImageButton + Государство
Значит, значение не равно нулю, и тип значения в точности соответствует тому, что я приведу.
Update
Output AssemblyQualifiedName, IsAssignableFrom, равно:
value.GetType().AssemblyQualifiedName;
typeof(State).AssemblyQualifiedName;
typeof(State).IsAssignableFrom(value.GetType());
value.GetType().IsAssignableFrom(typeof(State))
value is State
ReferenceEquals(value.GetType(), typeof(State))
Странный результат:
WinFormControls.ImageButton + State, WinFormControls, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = ноль
WinFormControls.ImageButton + State, WinFormControls, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = ноль
Ложь
Ложь
Ложь
Ложные
Два вопроса:
- Почему происходит ошибка?
- Как мне избежать этого во время разработки?