Looking for a more dynamic designer TypeConverter serialization in a VS10 .NET form

为君一笑 提交于 2020-12-13 04:23:25

问题


I have a list of a class which I serialize to the designer generated code with the following code:

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

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor) && value is ControlListManager.TargetSettings)
        {
            ConstructorInfo constructor = typeof(ControlListManager.TargetSettings).GetConstructor(new[] { typeof(object), typeof(string), typeof(DisplayModes), typeof(bool), typeof(int), typeof(int), typeof(int) });
            var target = value as ControlListManager.TargetSettings;
            var descriptor = new InstanceDescriptor(constructor, new[] { target.Target, target.Text, target.DisplayMode, target.Fade, target.HideTimeout, target.PaddingX, target.PaddingY }, true);
            return descriptor;
        }
        if (culture == null) { culture = CultureInfo.CurrentCulture; }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

This works well so far, but what bothers me is that I have to specify the types and values individually.

My first idea was to use GetConstructors() instead. But then to problem of the values still remains. I'm really confused about this problem since I actually write the function without knowing the amount of parameters - or only if it is "hardcoded".

Does anyone have any idea how this can be done better?

Edit: The data class

    [TypeConverter(typeof(TargetSettingsConverter))]
    public class TargetSettings : IEquatable<TargetSettings>
    {
        public object Target = new { };
        public string Text;
        public DisplayModes DisplayMode = DisplayModes.FollowXY;
        public bool Fade = true;
        public int HideTimeout;
        public int PaddingX;
        public int PaddingY;
        public bool Equals(TargetSettings other)
        {
            return other != null && (Target.Equals(other.Target));
        }
        public override bool Equals(object obj)
        {
            if (obj == null) { return false; }
            TargetSettings objAsPart = obj as TargetSettings;
            if (objAsPart == null) { return false; }
            return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return Target.GetHashCode();
        }
        public TargetSettings(object target, string text = "", DisplayModes displayMode = DisplayModes.FollowXY, bool fade = true, int hideTimeout = 0, int paddingX = 0, int paddingY = 0)
        {
            Target = target;
            Text = text;
            DisplayMode = displayMode;
            Fade = fade;
            HideTimeout = hideTimeout;
            PaddingX = paddingX;
            PaddingY = paddingY;
        }
    }

回答1:


Based on your question, you want to make your code more dynamic for the types and values.

Since the types and values you want to convert are all field types. I recommend that you use the reflection to do it.

You can get all the field types as the following:

 Type []tarr = typeof(TargetSettings).GetFields().Select(i => i.FieldType).ToArray();
 ConstructorInfo constructor = typeof(TargetSettings).GetConstructor(tarr);

You can get all the field values as the following:

object []oarr= typeof(TargetSettings).GetFields().Select(i => i.GetValue(target)).ToArray();
var descriptor = new InstanceDescriptor(constructor, oarr, true);

Full code:

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

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(InstanceDescriptor) && value is TargetSettings)
            {
                Type []tarr = typeof(TargetSettings).GetFields().Select(i => i.FieldType).ToArray();
                ConstructorInfo constructor = typeof(TargetSettings).GetConstructor(tarr);
                var target = value as TargetSettings;
                object []oarr= typeof(TargetSettings).GetFields().Select(i => i.GetValue(target)).ToArray();
                var descriptor = new InstanceDescriptor(constructor, oarr, true);
                return descriptor;
            }
            if (culture == null) { culture = CultureInfo.CurrentCulture; }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }


    [TypeConverter(typeof(TargetSettingsConverter))]
    public class TargetSettings : IEquatable<TargetSettings>
    {
        public object Target = new { };
        public string Text;
        public DisplayModes DisplayMode = DisplayModes.FollowXY;
        public bool Fade = true;
        public int HideTimeout;
        public int PaddingX;
        public int PaddingY;
        public bool Equals(TargetSettings other)
        {
            return other != null && (Target.Equals(other.Target));
        }
        public override bool Equals(object obj)
        {
            if (obj == null) { return false; }
            TargetSettings objAsPart = obj as TargetSettings;
            if (objAsPart == null) { return false; }
            return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return Target.GetHashCode();
        }
        public TargetSettings(object target, string text = "", DisplayModes displayMode = DisplayModes.FollowXY, bool fade = true, int hideTimeout = 0, int paddingX = 0, int paddingY = 0)
        {
            Target = target;
            Text = text;
            DisplayMode = displayMode;
            Fade = fade;
            HideTimeout = hideTimeout;
            PaddingX = paddingX;
            PaddingY = paddingY;
        }
    }

    public enum DisplayModes
    {
        FollowXY

    }


来源:https://stackoverflow.com/questions/64714234/looking-for-a-more-dynamic-designer-typeconverter-serialization-in-a-vs10-net-f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!