Re: Сложное свойство
От: V.Petrovski Беларусь  
Дата: 17.10.03 08:50
Оценка: 16 (4)
Здравствуйте, sniveller, Вы писали:

Вот все что надо сделать чтобы все работало. Кстати не важно struct или class

Сама сущность и её конвертор
    // можно поставить и class, т.к. при изменении его св-ва в PGrid будет создоваться заново экземпляр.
    // а вот в коде можно будет так testForm.Line.Width = 1 И это изменение не отловить в св-ве testForm.Line
    [TypeConverter(typeof(LineConverter))]
    public struct Line 
    {
        int width;
        Color color;
        public Line(int width, Color color)
        {
            this.width = width;
            this.color = color;
        }
        public int Width
        { 
            get
            {
                return width;
            }
            set
            {
                width = value;
            }
        }
        public Color Color
        { 
            get
            {
                return color;
            }
            set
            {
                color = value;
            }
        }
        public override string ToString()
        {
            return String.Format("{0} width {1}", color, width);
        }
    }

    public class LineConverter : TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(InstanceDescriptor))
            {
                return true; 
            }
            return base.CanConvertTo (context, destinationType);
        }
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if ((destinationType == typeof(InstanceDescriptor)) && (value is Line))
            {
                Line line = (Line)value;
                Type[] array = new Type[2];
                array[0] = typeof(int);
                array[1] = typeof(Color);
                ConstructorInfo info = typeof(Line).GetConstructor(array);
                if (info != null)
                {
                    object[] values = new object[2];
                    values[0] = line.Width;
                    values[1] = line.Color;
                    return new InstanceDescriptor(info, values); 
                }
             }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            return new Line((int)propertyValues["Width"],(Color)propertyValues["Color"]);
        }
        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            PropertyDescriptorCollection collection;
            string[]    props = new string[]{"Color", "Width"};
            collection = TypeDescriptor.GetProperties(typeof(Line), attributes);
            return collection.Sort(array); 
        }
        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
    }
}


А вот его использование


        private Line line = new Line(1,Color.Black);
        /// <summary>
        /// Линия
        /// </summary>
        [Browsable(true)]
        [Description("Линия")]
        [TypeConverter(typeof(LineConverter))]
        public Line Line
        {
            get
            {
                return line;
            }
            set
            {
            // если Line - struct, то мы сюда попопед при людом изменнии мв-в Line
            // а вот если class, то только при такой записи testForm.Line = линия
                line = value;
            }
        }


Вот как это выглядит в PropertyGrid



А так выглядит в коде

private void InitializeComponent()
{
...
    this.testForm.Line = new Line(1, System.Drawing.Color.Silver);
...
}
... << RSDN@Home 1.1 beta 1 silent>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.