Laden...

PropertyGrid TypeConverter Interval

Erstellt von dr4g0n76 vor 12 Jahren Letzter Beitrag vor 12 Jahren 4.654 Views
dr4g0n76 Themenstarter:in
2.921 Beiträge seit 2005
vor 12 Jahren
PropertyGrid TypeConverter Interval

EDIT: Hinweis vorneweg:

**Die beiden GetProperties Befehle **


PropertyInfo[] aPropertyInfo = k.GetType().GetProperties();
aPropertyInfo[1].SetValue(k, numArray[0],null);
aPropertyInfo[0].SetValue(k, numArray[1],null);

funktionieren hier nur so weil die Properties "Min" und "Max" des Intervalls direkt hintereinander kommen. Normalerweise sollte man die Properties hier anhand des Namens identifizieren.

Hi,

ich habe jeweils eine Klasse IntInterval, FloatInterval, ByteInterval, DoubleInterval
Jetzt wollte ich die Properties dieser Klassen im PropertyGrid anzeigen und ändern können,

wenn ich

PropertyGrid.SelectObject = objectOfIntervalType;

funktionierte es wunderbar.

Aber wenn ich das von der Filterklasse gemacht habe, hat es nicht mehr funktioniert. Die Properties wurden zwar angezeigt (die Überladung der ToString-Methode in der Intervall-Klasse macht es möglich), aber ich konnte die Properties nicht editieren.

Hier meine Lösung Dazu.

Der Type Converter:


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;

using System.Globalization;
using PropertyGridExtendedTypeTest.Types.Interval;

namespace PropertyGridExtendedTypeTest
{
    /// <summary>
    /// Double Interval Converter
    /// </summary>
    public class IntervalConverter<T, K> : TypeConverter where K : new()
    {
        /// <summary>
        /// Can convert from...
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
        }

        /// <summary>
        /// Determine if conversion is possible
        /// </summary>
        /// <param name="context"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
        }

        /// <summary>
        /// Convert back
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string str = value as string;
            if (str == null)
            {
                return base.ConvertFrom(context, culture, value);
            }
            string str2 = str.Trim();
            if (str2.Length == 0)
            {
                return null;
            }
            if (culture == null)
            {
                culture = CultureInfo.CurrentCulture;
            }
            char ch = culture.TextInfo.ListSeparator[0];
            string[] strArray = str2.Split(new char[] { ch });
            T[] numArray = new T[strArray.Length];
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(double));
            for (int i = 0; i < numArray.Length; i++)
            {
                numArray[i] = (T)converter.ConvertFromString(context, culture, strArray[i]);
            }
            if (numArray.Length != 2)
            {
                //throw new ArgumentException("TextParseFailedFormat", new object[] { str2, "Width,Height" });
            }
            K k = new K();
            PropertyInfo[] aPropertyInfo = k.GetType().GetProperties();
            aPropertyInfo[1].SetValue(k, numArray[0],null);
            aPropertyInfo[0].SetValue(k, numArray[1],null);

            //numArray[0], numArray[1]
            return k;
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }
            if (value is DoubleInterval)
            {
                if (destinationType == typeof(string))
                {
                    DoubleInterval doubleInterval = (DoubleInterval)value;
                    if (culture == null)
                    {
                        culture = CultureInfo.CurrentCulture;
                    }
                    string separator = culture.TextInfo.ListSeparator + " ";
                    TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
                    string[] strArray = new string[2];
                    int num = 0;
                    strArray[num++] = converter.ConvertToString(context, culture, doubleInterval.Min);
                    strArray[num++] = converter.ConvertToString(context, culture, doubleInterval.Max);
                    return string.Join(separator, strArray);
                }
                if (destinationType == typeof(InstanceDescriptor))
                {
                    Size size2 = (Size)value;
                    ConstructorInfo constructor = typeof(Size).GetConstructor(new Type[] { typeof(int), typeof(int) });
                    if (constructor != null)
                    {
                        return new InstanceDescriptor(constructor, new object[] { size2.Width, size2.Height });
                    }
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
        {
            if (propertyValues == null)
            {
                throw new ArgumentNullException("propertyValues");
            }
            object obj2 = propertyValues["Width"];
            object obj3 = propertyValues["Height"];
            if (((obj2 == null) || (obj3 == null)) || (!(obj2 is int) || !(obj3 is int)))
            {
                //throw new ArgumentException(SR.GetString("PropertyValueInvalidEntry"));
            }
            return new Size((int)obj2, (int)obj3);
        }

        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            return TypeDescriptor.GetProperties(typeof(Size), attributes).Sort(new string[] { "Width", "Height" });
        }

        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
    }

}

Und der Aufruf für eine der Intervallklassen als Beispiel:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;

namespace PropertyGridExtendedTypeTest.Types.Interval
{
    /// <summary>
    /// The boundaries are momentarily included (>= ...)
    /// If they should be excluded use ONLY greater or smaller sign
    /// </summary>
    [DebuggerDisplay("[{m_dMin}, {m_dMax}]")]
    [DefaultPropertyAttribute("Interval")]
    [TypeConverter(typeof(IntervalConverter<double, DoubleInterval>))]
    public class DoubleInterval : IComparable<DoubleInterval>, ICloneable, ICustomTypeDescriptor
    {
        protected double m_dMin = 0.1f;
        protected double m_dMax = 0.2f;

        public DoubleInterval()
        {
        }

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="_dMin"></param>
        /// <param name="_dMax"></param>
        public DoubleInterval(double _dMin, double _dMax)
        {
            m_dMin = _dMin;
            m_dMax = _dMax;
        }

        /// <summary>
        /// Max value of this interval
        /// </summary>
        [DisplayName("Max")]
        public double Max
        {
            get { return m_dMax; }
            set { m_dMax = value; }
        }

        /// <summary>
        /// Min value of this interval
        /// </summary>
        [DisplayName("Min")]
        public double Min
        {
            get { return m_dMin; }
            set { m_dMin = value; }
        }

        /// <summary>
        /// Returns true, if the value is inside given interval
        /// </summary>
        /// <param name="_dValue"></param>
        /// <returns></returns>
        public bool Contains(double _dValue)
        {
            return _dValue >= m_dMin && _dValue <= m_dMax;
        }

        /// <summary>
        /// Check if the current interval completely contains given interval
        /// </summary>
        /// <param name="_doubleInterval"></param>
        /// <returns></returns>
        public bool Contains(DoubleInterval _doubleInterval)
        {
            return m_dMin<=_doubleInterval.m_dMin && m_dMax>= _doubleInterval.m_dMax;
        }

        /// <summary>
        /// This will check if an interval is overlapping, i.e. concrete:
        /// True if one of the given boundaries is contained inside the interval.
        /// The other boundary has to be outside the interval.
        /// </summary>
        /// <param name="_doubleInterval"></param>
        /// <returns></returns>
        public bool Intersects(DoubleInterval _doubleInterval)
        {
            return 
                (Contains(_doubleInterval.m_dMax) && !Contains(_doubleInterval.m_dMin))
                || (Contains(_doubleInterval.m_dMin) && !Contains(_doubleInterval.m_dMax))
                ;
        }

        /// <summary>
        /// This returns the size of the interval.
        /// Also negative sizes are allowed to show the direction.
        /// Use Abs(Size) if direction is unimportant
        /// </summary>
        public double Size
        {
            get { return m_dMax - m_dMin; }
        }

        #region IComparable<DoubleInterval> Members

        /// <summary>
        /// An interval is bigger if its size is bigger
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(DoubleInterval other)
        {
            return this.Size.CompareTo(other.Size);
        }

        #endregion

        /// <summary>
        /// Get interval as string in notation e.g. [0,1]
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("[{0},{1}]", m_dMin, m_dMax);
        }

        #region ICloneable Members

        /// <summary>
        /// Use this to clone the interval
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return new DoubleInterval(this.m_dMin, this.m_dMax);
        }

        #endregion

        #region ICustomTypeDescriptor Members

        /// <summary>
        /// Returns a collection of custom attributes for this instance of a component.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.ComponentModel.AttributeCollection"/> containing the attributes for this object.
        /// </returns>
        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }

        /// <summary>
        /// Returns the class name of this instance of a component.
        /// </summary>
        /// <returns>
        /// The class name of the object, or null if the class does not have a name.
        /// </returns>
        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }

        /// <summary>
        /// Returns the name of this instance of a component.
        /// </summary>
        /// <returns>
        /// The name of the object, or null if the object does not have a name.
        /// </returns>
        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }

        /// <summary>
        /// Returns a type converter for this instance of a component.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
        /// </returns>
        public TypeConverter GetConverter()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the default event for this instance of a component.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.ComponentModel.EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
        /// </returns>
        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }

        /// <summary>
        /// Returns the default property for this instance of a component.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have properties.
        /// </returns>
        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }

        /// <summary>
        /// Returns an editor of the specified type for this instance of a component.
        /// </summary>
        /// <param name="editorBaseType">A <see cref="T:System.Type"/> that represents the editor for this object.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
        /// </returns>
        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }

        /// <summary>
        /// Returns the events for this instance of a component using the specified attribute array as a filter.
        /// </summary>
        /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
        /// <returns>
        /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the filtered events for this component instance.
        /// </returns>
        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this, attributes, true);
        }

        /// <summary>
        /// Returns the events for this instance of a component.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the events for this component instance.
        /// </returns>
        public EventDescriptorCollection GetEvents()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the properties for this instance of a component using the attribute array as a filter.
        /// </summary>
        /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
        /// </returns>
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the properties for this instance of a component.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the properties for this component instance.
        /// </returns>
        public PropertyDescriptorCollection GetProperties()
        {
            return TypeDescriptor.GetProperties(this, true);
        }

        /// <summary>
        /// Returns an object that contains the property described by the specified property descriptor.
        /// </summary>
        /// <param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that represents the owner of the specified property.
        /// </returns>
        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        #endregion
    }
}

Ich hoffe das hilft euch weiter.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.