none
how to use struct as control property RRS feed

  • Question

  • I have a problem with a property of my custom control. The property is a struct. To expand this property in the property browser i have made a TypeConverter. When i try to change a value of that property,  i find the property value can not save, when reopen the form the value lost.

    want the custom struct property like the Size property, vs2010 auto create code:

    this.rwPanel1.Size = new System.Drawing.Size(468, 469);

    but vs2010 cant not create this code.

    public partial class TreeView2 : TreeView { private string idMember; private string codeMember; private string nameMember; private string levelMember; private string parentMember; private string enabledMember; private string leafMember; private string typeMember; public TreeNodeMember NodeMember { get { return new TreeNodeMember(idMember, codeMember, nameMember, levelMember, leafMember, enabledMember, typeMember, parentMember); } set { idMember = value.IDMember; codeMember = value.CodeMember; nameMember = value.NameMember; levelMember = value.LevelMember; leafMember = value.LeafMember; enabledMember = value.EnabledMember; typeMember = value.TypeMember; parentMember = value.ParentMember; ClearTree(); } } public TreeView() { InitializeComponent(); idMember = "ID"; codeMember = "Code"; nameMember = "Name"; parentMember = "ParentID"; } } [TypeConverter(typeof(TreeNodeMemberConverter))] public struct TreeNodeMember {

    } public class TreeNodeMemberConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == null) { throw new ArgumentNullException("destinationType"); } if (value is TreeNodeMember) { if (destinationType == typeof(string)) { TreeNodeMember member = (TreeNodeMember)value; return member.ToString(); } } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) { return true; } return base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { string strValue = value as string; if (strValue != null) { string text = strValue.Trim(); if (text.Length == 0) { return null; } else { TreeNodeMember member = new TreeNodeMember(); member.Parse(text); return member; } } return base.ConvertFrom(context, culture, value); } public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) { if (propertyValues == null) { throw new ArgumentNullException("propertyValues"); } object id = propertyValues["IDMember"]; object code = propertyValues["CodeMember"]; object name = propertyValues["NameMember"]; object level = propertyValues["LevelMember"]; object leaf = propertyValues["LeafMember"]; object type = propertyValues["TypeMember"]; object enabled = propertyValues["EnabledMember"]; object parent = propertyValues["ParentMember"]; TreeNodeMember member = new TreeNodeMember((string)id, (string)code, (string)name, (string)level, (string)leaf, (string)enabled, (string)type, (string)parent); return member; } public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) { return true; } public override PropertyDescriptorCollection GetProperties( ITypeDescriptorContext context, object value, Attribute[] attributes) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties( typeof(TreeNodeMember), attributes); return props.Sort(new string[] { "IDMember", "CodeMember", "NameMember", "ParentMember", "LevelMember", "LeafMember", "EnabledMember", "TypeMember" }); } public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } }




    • Edited by 老邸 Thursday, November 29, 2012 1:58 AM
    Thursday, November 22, 2012 7:39 AM

All replies

  • Hi 老邸,

    I know you have posted this question on china MSDN Forum: http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/64d59292-b0ff-4dae-9424-6774d047b9c8/#c24c50b8-3dc2-4a4a-8308-3499066298fc 

    I also tried your code, and I reproduced it.

    And now, I am trying to involve some other one into this thread, please wait it patiently. Thank you.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, November 26, 2012 5:29 AM
    Moderator
  • Thank you, I hope to get an answer as soon as possible!

    Tuesday, November 27, 2012 1:24 AM
  • Hi,

    I tried your example, but couldn't get it to build. Looking at a simpler example, I reproduced the same issue. I believe you need to do two things.

    First, decorate your struct so that it is Serializable. For example,

            [Serializable]
            public struct TreeNodeMember
            {
            }

    Second, move the TypeConverter decoration to the public property (NodeMember). For example,

            [TypeConverter(typeof(TreeNodeMemberConverter))]         
            public TreeNodeMember NodeMember
          {
              get
              {

               ... 
             }
              set
              {
            ...
              }
          }

    When I do this, the designer serializes the data for the structure into the RESX file for the Form, and adds the appropriate code to set NodeMember from within InitializeComponent. After doing this, the values are persisted for NodeMember when closing and reopening the Form (provided it was saved, of course).

    Hope this helps,

    Keith Fink [MSFT]


    Keith Fink Microsoft

    Tuesday, December 4, 2012 10:12 PM
  • Earlier, I tried to do Serializable, but it can not work too. The designer serializes the data , and adds the appropriate code to set NodeMember from within InitializeComponent, but it can not compile.

    the control's struct property like the Size and Location, vs2010 auto create code:

    this.panel1.Size = new System.Drawing.Size(468, 469);

    not this

    this.TreeView2.NodeMember = ((TreeNodeMember)(resources.GetObject("TreeView2.NodeMember")));

    Monday, December 10, 2012 9:51 AM
  • This TreeNodeMemberConverter class can work on my computer, but on other computer can not work.

    what's wrong?

        public class TreeNodeMemberConverter : 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 == null)
                {
                    throw new ArgumentNullException("destinationType");
                }
                if (value is TreeNodeMember)
                {
                    if (destinationType == typeof(string))
                    {
                        TreeNodeMember member = (TreeNodeMember)value;
                        return member.ToString();
                    }
                    else if (destinationType == typeof(InstanceDescriptor))
                    {
                        TreeNodeMember member = (TreeNodeMember)value;
                        Type[] argTypes = { typeof(String), typeof(String), typeof(String), typeof(String), 
                                            typeof(String), typeof(String), typeof(String), typeof(String) };
                        object[] properties = { member.IDMember, member.CodeMember, member.NameMember, 
                                                member.LevelMember, member.LeafMember, member.EnabledMember, 
                                                member.TypeMember, member.ParentMember };
                        ConstructorInfo ci = typeof(TreeNodeMember).GetConstructor(argTypes);
                        return new InstanceDescriptor(ci, properties);
                    }
                }
                return base.ConvertTo(context, culture, value, destinationType);
            }
    
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                if (sourceType == typeof(string))
                {
                    return true;
                }
                return base.CanConvertFrom(context, sourceType);
            }
    
            public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
            {
                string strValue = value as string;
                if (strValue != null)
                {
                    string text = strValue.Trim();
                    if (text.Length == 0)
                    {
                        return null;
                    }
                    else
                    {
                        TreeNodeMember member = new TreeNodeMember();
                        member.Parse(text);
                        return member;
                    }
                }
    
                return base.ConvertFrom(context, culture, value);
            }
    
            public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
            {
                if (propertyValues == null)
                {
                    throw new ArgumentNullException("propertyValues");
                }
                object id = propertyValues["IDMember"];
                object code = propertyValues["CodeMember"];
                object name = propertyValues["NameMember"];
                object level = propertyValues["LevelMember"];
                object leaf = propertyValues["LeafMember"];
                object type = propertyValues["TypeMember"];
                object enabled = propertyValues["EnabledMember"];
                object parent = propertyValues["ParentMember"];
    
                TreeNodeMember member = new TreeNodeMember((id as string), (code as string), (name as string),
                    (level as string), (leaf as string), (enabled as string), (type as string), (parent as string));
                return member;
            }
    
            public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
            {
                return true;
            }
    
            public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
            {
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(TreeNodeMember), attributes);
                return props.Sort(new string[] { "IDMember", "CodeMember", "NameMember", "ParentMember", "LevelMember", "LeafMember", "EnabledMember", "TypeMember" });
            }
    
            public override bool GetPropertiesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
        }

    Wednesday, December 19, 2012 8:26 AM