在 VS10 .NET 表单中寻找更动态的设计器 TypeConverter 序列化

Posted

技术标签:

【中文标题】在 VS10 .NET 表单中寻找更动态的设计器 TypeConverter 序列化【英文标题】:Looking for a more dynamic designer TypeConverter serialization in a VS10 .NET form 【发布时间】:2021-02-19 03:56:41 【问题描述】:

我有一个类列表,我使用以下代码将其序列化到设计器生成的代码:

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);
    

到目前为止,这很好用,但困扰我的是我必须单独指定类型和值。

我的第一个想法是改用 GetConstructors()。但是,价值观的问题仍然存在。我真的对这个问题感到困惑,因为我实际上是在不知道参数数量的情况下编写函数 - 或者仅在它是“硬编码”的情况下编写的。

有没有人知道如何才能做得更好?

编辑:数据类

    [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;
        
    

【问题讨论】:

根据我的测试,我找不到类 ControlListManager.TargetSettings。是你自己创建的类吗?如果有,请提供。 当然我会更新我的问题。 【参考方案1】:

根据您的问题,您希望使代码的类型和值更具动态性。

由于要转换的类型和值都是字段类型。我建议你使用反射来做。

你可以得到所有的字段类型如下:

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

您可以通过以下方式获取所有字段值:

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

完整代码:

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

    

【讨论】:

以上是关于在 VS10 .NET 表单中寻找更动态的设计器 TypeConverter 序列化的主要内容,如果未能解决你的问题,请参考以下文章

.NET VS win表单项目中的序列化顺序(设计器代码)问题

你知道标签+文本框数据输入布局的更动态的网格吗?

VS 2010 设计器在 Windows7 中出现错误“找不到类型 XYZ”。在 XP 中运行良好

VB.NET 视觉继承:Friend VS Protected

使用框架 4.7.2 运行 SDK 项目的 vs2019 中的控件和表单缺少图标和视图设计器选项

在 VS 2010 中禁用 WPF 设计器?