Reza552 Ответов: 0

Ошибка при нажатии кнопки "сохранить все" на панели инструментов


Всем привет,

Цель:
Создайте пользовательское свойство типа Размер свойство во многих элементах управления настольными приложениями 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

    }
}


Что я уже пробовал:

Создайте пользовательское свойство, подобное поведению свойства "размер".

0 Ответов