Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To go down this route, you would need to create a custom <code>PropertyDescriptor</code> per property. You would then expose that via a custom <code>TypeConverter</code>, or (alternatively) <code>ICustomTypeDescriptor</code>/<code>TypeDescriptionProvider</code>. Example:</p> <pre><code>using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; [TypeConverter(typeof(CustomObjectType.CustomObjectConverter))] public class CustomObjectType { [Category("Standard")] public string Name { get; set; } private readonly List&lt;CustomProperty&gt; props = new List&lt;CustomProperty&gt;(); [Browsable(false)] public List&lt;CustomProperty&gt; Properties { get { return props; } } private Dictionary&lt;string, object&gt; values = new Dictionary&lt;string, object&gt;(); public object this[string name] { get { object val; values.TryGetValue(name, out val); return val; } set { values.Remove(name); } } private class CustomObjectConverter : ExpandableObjectConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { var stdProps = base.GetProperties(context, value, attributes); CustomObjectType obj = value as CustomObjectType; List&lt;CustomProperty&gt; customProps = obj == null ? null : obj.Properties; PropertyDescriptor[] props = new PropertyDescriptor[stdProps.Count + (customProps == null ? 0 : customProps.Count)]; stdProps.CopyTo(props, 0); if (customProps != null) { int index = stdProps.Count; foreach (CustomProperty prop in customProps) { props[index++] = new CustomPropertyDescriptor(prop); } } return new PropertyDescriptorCollection(props); } } private class CustomPropertyDescriptor : PropertyDescriptor { private readonly CustomProperty prop; public CustomPropertyDescriptor(CustomProperty prop) : base(prop.Name, null) { this.prop = prop; } public override string Category { get { return "Dynamic"; } } public override string Description { get { return prop.Desc; } } public override string Name { get { return prop.Name; } } public override bool ShouldSerializeValue(object component) { return ((CustomObjectType)component)[prop.Name] != null; } public override void ResetValue(object component) { ((CustomObjectType)component)[prop.Name] = null; } public override bool IsReadOnly { get { return false; } } public override Type PropertyType { get { return prop.Type; } } public override bool CanResetValue(object component) { return true; } public override Type ComponentType { get { return typeof(CustomObjectType); } } public override void SetValue(object component, object value) { ((CustomObjectType)component)[prop.Name] = value; } public override object GetValue(object component) { return ((CustomObjectType)component)[prop.Name] ?? prop.DefaultValue; } } } public class CustomProperty { public string Name { get; set; } public string Desc { get; set; } public object DefaultValue { get; set; } Type type; public Type Type { get { return type; } set { type = value; DefaultValue = Activator.CreateInstance(value); } } } static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); var obj = new CustomObjectType { Name = "Foo", Properties = { new CustomProperty { Name = "Bar", Type = typeof(int), Desc = "I'm a bar"}, new CustomProperty { Name = "When", Type = typeof(DateTime), Desc = "When it happened"}, } }; Application.Run(new Form { Controls = { new PropertyGrid { SelectedObject = obj, Dock = DockStyle.Fill } } }); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload