Ошибка при нажатии кнопки "сохранить все" на панели инструментов
Всем привет,
Цель:
Создайте пользовательское свойство типа Размер свойство во многих элементах управления настольными приложениями windows имеет точно такое же поведение во время разработки и во время выполнения. Я назвал его, StartLength.
Примечание: Я пропустил все измененные обработчики событий.
Ошибка:
Я изменяю значение StartLength свойство из PropertyGrid во время разработки, а затем нажмите кнопку панели инструментов "сохранить все" в Visual Studio 2013 (установлена на Windows 10 x64) и, наконец, перестройте решение, все в порядке.
Но, когда повторяю то же самое во второй раз, я получаю это сообщение об ошибке:
Генерация кода для свойства 'StartLength' не удалась. Ошибка была такова: "StartLengthConverter' не может преобразовать 'TestApp2.MyClasses.Стартовая длина системы "до".ComponentModel.Дизайн.Сериализация.InstanceDescriptor'.'
Как:
Я создаю новое приложение c# Windows Form (.Net framework 4) с VS2013 и называю его TestApp2 Затем я добавляю две папки в свой проект. Один из них MyClasses а еще есть MyControls Теперь я добавляю два класса (StartLength и StartLengthConverter) к MyClasses папка и пользовательский элемент управления (MyTextBox) к MyControls папка. Источник этих классов приведен ниже. Теперь я перестраиваю решение и появляюсь MyTextBox пользовательский элемент управления в Toolbox. Перетащите его на форму 1, сохраните и перестройте проект, а затем попробуйте изменить StartLength недвижимость в MyTextBox.
Примечание: это TestApp2.zip ссылка для скачивания.
Источник стартовой длины:
#region using using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; using System.Text; #endregion namespace TestApp2.MyClasses { [ComVisible(true)] [Serializable] [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")] [TypeConverter(typeof(StartLengthConverter))] public struct StartLength { public static readonly StartLength Empty = new StartLength(); #region Properties #region Start public int Start { get { return _start; } set { _start = value; } } private int _start; #endregion #region Length public int Length { get { return _length; } set { _length = value; } } private int _length; #endregion #region IsEmpty [Browsable(false)] public bool IsEmpty { get { return (_start == 0) && (_length == 0); } } #endregion #endregion #region Methods #region StartLength public StartLength(int start, int length) { _start = start; _length = length; } #endregion #region Add public static StartLength Add(StartLength left, StartLength right) { return new StartLength(left.Start + right.Start, left.Length + right.Length); } #endregion #region Subtract public static StartLength Subtract(StartLength left, StartLength right) { return new StartLength(left.Start - right.Start, left.Length - right.Length); } #endregion #region operator + public static StartLength operator +(StartLength left, StartLength right) { return Add(left, right); } #endregion #region operator - public static StartLength operator -(StartLength left, StartLength right) { return Subtract(left, right); } #endregion #region operator == public static bool operator ==(StartLength left, StartLength right) { return (left.Start == right.Start) && (left.Length == right.Length); } #endregion #region operator != public static bool operator !=(StartLength left, StartLength right) { return !(left == right); } #endregion #region ToString public override string ToString() { return "{Start=" + _start.ToString(CultureInfo.CurrentCulture) + ", Length=" + _length.ToString(CultureInfo.CurrentCulture) + "}"; } #endregion #region Equals public override bool Equals(object obj) { if (obj is StartLength) { StartLength startLength = (StartLength)obj; return (_start == startLength.Start) && (_length == startLength.Length); } return false; } #endregion #region GetHashCode public override int GetHashCode() { return _start ^ _length; } #endregion #endregion } }
Источник StartLengthConverter:
#region using using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; #endregion namespace TestApp2.MyClasses { public class StartLengthConverter : TypeConverter { #region Methods #region CanConvertFrom public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) return true; return base.CanConvertFrom(context, sourceType); } #endregion #region CanConvertTo public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(InstanceDescriptor)) return true; return base.CanConvertTo(context, destinationType); } #endregion #region ConvertFrom [SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")] public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { string strValue = value as string; if (strValue != null) { string text = strValue.Trim(); if (text.Length == 0) return null; if (culture == null) culture = CultureInfo.CurrentCulture; char sep = culture.TextInfo.ListSeparator[0]; string[] tokens = text.Split(new char[] { sep }); int[] values = new int[tokens.Length]; TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(int)); for (int i = 0; i < values.Length; i++) values[i] = (int)intConverter.ConvertFromString(context, culture, tokens[i]); if (values.Length == 2) return new StartLength(values[0], values[1]); throw new ArgumentException("The format error. It must be 'Start,Length'."); } return base.ConvertFrom(context, culture, value); } #endregion #region ConvertTo public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == null) throw new ArgumentNullException("destinationType"); if (value is StartLength) { if (destinationType == typeof(string)) { if (culture == null) culture = CultureInfo.CurrentCulture; StartLength startLength = (StartLength)value; string sep = culture.TextInfo.ListSeparator + " "; TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(int)); string[] args = new string[2]; int nArg = 0; args[nArg++] = intConverter.ConvertToString(context, culture, startLength.Start); args[nArg++] = intConverter.ConvertToString(context, culture, startLength.Length); return string.Join(sep, args); } if (destinationType == typeof(InstanceDescriptor)) { StartLength startLength = (StartLength)value; ConstructorInfo ctor = typeof(StartLength).GetConstructor(new Type[] { typeof(int), typeof(int) }); if (ctor != null) return new InstanceDescriptor(ctor, new object[] { startLength.Start, startLength.Length }); } } return base.ConvertTo(context, culture, value, destinationType); } #endregion #region CreateInstance [SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")] [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) { if (propertyValues == null) throw new ArgumentNullException("propertyValues"); object start = propertyValues["Start"]; object length = propertyValues["Length"]; if ((start == null) || (length == null) || (!(start is int)) || (!(length is int))) throw new ArgumentException("Invalid propertyValues entry."); return new StartLength((int)start, (int)length); } #endregion #region GetCreateInstanceSupported public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) { return true; } #endregion #region GetProperties public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(StartLength), attributes); return props.Sort(new string[] { "Start", "Length" }); } #endregion #region GetPropertiesSupported public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } #endregion #endregion } }
Источник MyTextBox:
#region using using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using TestApp2.MyClasses; #endregion namespace TestApp2.MyControls { [DefaultEvent("TextChanged")] [DefaultProperty("Text")] [ToolboxItem(true)] [ToolboxBitmap(typeof(TextBox))] public partial class MyTextBox : TextBox { #region Properties #region StartLength [Browsable(true)] [Category("My")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [EditorBrowsable(EditorBrowsableState.Always)] public virtual StartLength StartLength { get { return _startLength; } set { _startLength = value; } } private StartLength _startLength = new StartLength(0, 0); #region DefaultStartLength private StartLength DefaultStartLength { get { return new StartLength(0, 0); } } #endregion #region ResetStartLength private void ResetStartLength() { this.StartLength = DefaultStartLength; } #endregion #region ShouldSerializeStartLength private bool ShouldSerializeStartLength() { return !(this.StartLength.Equals(DefaultStartLength)); } #endregion #endregion #endregion #region Methods #region MyTextBox public MyTextBox() { InitializeComponent(); } #endregion #endregion } }
Что я уже пробовал:
Создайте пользовательское свойство, подобное поведению свойства "размер".