zhaojiahai / aforge

Automatically exported from code.google.com/p/aforge
Other
0 stars 0 forks source link

Please provide type converters for NXTBrick internal structs #194

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I would like to use property grid to edit NXTBrick properties. I cant use 
ExpandableObjectConverter because it doesn't work on structs.

You can use belove sample code as a base to create needed converters.

// System.Windows.Forms.PaddingConverter
public class PaddingConverter : TypeConverter
{
    // Methods
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string str = value as string;
        if (str == null)
        {
            return base.ConvertFrom(context, culture, value);
        }
        str = str.Trim();
        if (str.Length == 0)
        {
            return null;
        }
        if (culture == null)
        {
            culture = CultureInfo.CurrentCulture;
        }
        char ch = culture.TextInfo.ListSeparator[0];
        string[] strArray = str.Split(new char[] { ch });
        int[] numArray = new int[strArray.Length];
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
        for (int i = 0; i < numArray.Length; i++)
        {
            numArray[i] = (int) converter.ConvertFromString(context, culture, strArray[i]);
        }
        if (numArray.Length != 4)
        {
            throw new ArgumentException(SR.GetString("TextParseFailedFormat", new object[] { "value", str, "left, top, right, bottom" }));
        }
        return new Padding(numArray[0], numArray[1], numArray[2], numArray[3]);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == null)
        {
            throw new ArgumentNullException("destinationType");
        }
        if (value is Padding)
        {
            if (destinationType == typeof(string))
            {
                Padding padding = (Padding) value;
                if (culture == null)
                {
                    culture = CultureInfo.CurrentCulture;
                }
                string separator = culture.TextInfo.ListSeparator + " ";
                TypeConverter converter = TypeDescriptor.GetConverter(typeof(int));
                string[] strArray = new string[4];
                int num = 0;
                strArray[num++] = converter.ConvertToString(context, culture, padding.Left);
                strArray[num++] = converter.ConvertToString(context, culture, padding.Top);
                strArray[num++] = converter.ConvertToString(context, culture, padding.Right);
                strArray[num++] = converter.ConvertToString(context, culture, padding.Bottom);
                return string.Join(separator, strArray);
            }
            if (destinationType == typeof(InstanceDescriptor))
            {
                Padding padding2 = (Padding) value;
                if (padding2.ShouldSerializeAll())
                {
                    return new InstanceDescriptor(typeof(Padding).GetConstructor(new Type[] { typeof(int) }), new object[] { padding2.All });
                }
                return new InstanceDescriptor(typeof(Padding).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int) }), new object[] { padding2.Left, padding2.Top, padding2.Right, padding2.Bottom });
            }
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (propertyValues == null)
        {
            throw new ArgumentNullException("propertyValues");
        }
        Padding padding = (Padding) context.PropertyDescriptor.GetValue(context.Instance);
        int all = (int) propertyValues["All"];
        if (padding.All != all)
        {
            return new Padding(all);
        }
        return new Padding((int) propertyValues["Left"], (int) propertyValues["Top"], (int) propertyValues["Right"], (int) propertyValues["Bottom"]);
    }

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

    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        return TypeDescriptor.GetProperties(typeof(Padding), attributes).Sort(new string[] { "All", "Left", "Top", "Right", "Bottom" });
    }

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

Original issue reported on code.google.com by krzysztof.blacha on 29 Mar 2011 at 3:19

GoogleCodeExporter commented 8 years ago
NXTBrick has nothing to do with UI, so why should we reference 
Systen.Windows.Forms from it (for PaddingConverter) ?

What about:
1) Do all the UI related code in your application?
2) If you need to extend something in NXTBrick, but you don't want to modify 
its source, then what about Extension Methods ???:
http://msdn.microsoft.com/en-us/library/bb383977.aspx

(just trying to understand the use case ... don't want to mess the library with 
something, which is very user specific)

Original comment by andrew.k...@gmail.com on 8 Apr 2011 at 8:49

GoogleCodeExporter commented 8 years ago
I've got me wrong. I will try to explain the problem in greater detail. And I 
think you don't need to reference SWF. Please check this scenario: Say you got 
an application (Forms) and you need to update motor state using PropertyGrid 
control control. Say application's user enter or selects needed settings and 
applyies them to the NXTbrick. So you create something like MyNXTBrickSettings 
and add a MotorA property of type NXTBrick.MotorState to it. Than you 
instantiate (probably in form's Load event or similar) your settings class and 
then assign it to propertyGrid's SelectedObject property to allow user access 
it. This would be fine but property grid doesn't allow to expand on struct 
properites. Please refer to ExpandableObjectConverter class. There are some 
workarounds like an proxy class (ugly and needs a lot of work - can send a 
sample). The simplest solution is not use struct for NXBrick.*State types. Is 
it possible?

Original comment by krzysztof.blacha on 8 Apr 2011 at 9:12

GoogleCodeExporter commented 8 years ago
Turned NXT structures into classes and provided properties for them (many of 
them are read-only since those are supposed to be set by framework, not by 
user).

Committed in revision 1415. Will be released in version 2.1.6.

Original comment by andrew.k...@gmail.com on 11 Apr 2011 at 8:14

GoogleCodeExporter commented 8 years ago
Great to see your message but have one question should really SensorType and 
SensorMode be readonly? And of course if I understand correctly those are 
breaking changes because previously all setters were available (struct)?

Original comment by krzysztof.blacha on 11 Apr 2011 at 9:43

GoogleCodeExporter commented 8 years ago
The SensorValue class is used only in one method: GetSensorValue( Sensor 
sensor, out SensorValues sensorValues ). So it is OK. Sensor mode/type is set 
using different method SetSensorMode(), not using class.

Yep, it may break a bit. But users should not be using those structures in such 
scenarios when they set fields there.

Original comment by andrew.k...@gmail.com on 12 Apr 2011 at 8:16

GoogleCodeExporter commented 8 years ago

Original comment by andrew.k...@gmail.com on 28 Jul 2011 at 9:45

GoogleCodeExporter commented 8 years ago

Original comment by andrew.k...@gmail.com on 3 Aug 2011 at 7:52