title: Custom (Dynamic) Properties - WPF Xceed Property Grid
body: <p>I need to add custom properties to the WPF Xceed Property Grid control during runtime.  The best solution that I could find is the one presented here:</p>
  
  <p><a href="https://stackoverflow.com/questions/313822/how-to-modify-propertygrid-at-runtime-add-remove-property-and-dynamic-types-enu">How to modify PropertyGrid at runtime (add/remove property and dynamic types/enums)</a></p>
  
  <p>However it only works for the WinForms Property Grid control.  See below for code, and the result that I am getting.</p>
  
  <p>I'm not an expert in this field at all.  Is it possible to make the code compatible with the Xceed Property Grid control?</p>
  
  <p><a href="https://i.stack.imgur.com/0R3Vr.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0R3Vr.jpg" alt="enter image description here"></a></p>
  
  <pre><code>        CustomClass myProperties = new CustomClass();
  
          propertyGrid.SelectedObject = myProperties;
  
          myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true,"Cat1"));
          myProperties.Add(new CustomProperty("Surname", "Bendo", typeof(string), false, true, "Cat1"));
          myProperties.Add(new CustomProperty("Card", "Visa", typeof(string), false, true, "Cat2"));
          myProperties.Add(new CustomProperty("Bank", "SB", typeof(string), false, true, "Cat2"));
  
          propertyGrid.Update();
  </code></pre>
  
  <p>Custom class:</p>
  
  <pre><code>    /// &lt;summary&gt;
      /// CustomClass (Which is binding to property grid)
      /// &lt;/summary&gt;
      public class CustomClass : CollectionBase, ICustomTypeDescriptor
      {
          /// &lt;summary&gt;
          /// Add CustomProperty to Collectionbase List
          /// &lt;/summary&gt;
          /// &lt;param name="Value"&gt;&lt;/param&gt;
          public void Add(CustomProperty Value)
          {
              base.List.Add(Value);
          }
  
          /// &lt;summary&gt;
          /// Remove item from List
          /// &lt;/summary&gt;
          /// &lt;param name="Name"&gt;&lt;/param&gt;
          public void Remove(string Name)
          {
              foreach (CustomProperty prop in base.List)
              {
                  if (prop.Name == Name)
                  {
                      base.List.Remove(prop);
                      return;
                  }
              }
          }
  
          /// &lt;summary&gt;
          /// Indexer
          /// &lt;/summary&gt;
          public CustomProperty this[int index]
          {
              get
              {
                  return (CustomProperty)base.List[index];
              }
              set
              {
                  base.List[index] = (CustomProperty)value;
              }
          }
  
  
          #region "TypeDescriptor Implementation"
          /// &lt;summary&gt;
          /// Get Class Name
          /// &lt;/summary&gt;
          /// &lt;returns&gt;String&lt;/returns&gt;
          public String GetClassName()
          {
              return TypeDescriptor.GetClassName(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetAttributes
          /// &lt;/summary&gt;
          /// &lt;returns&gt;AttributeCollection&lt;/returns&gt;
          public AttributeCollection GetAttributes()
          {
              return TypeDescriptor.GetAttributes(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetComponentName
          /// &lt;/summary&gt;
          /// &lt;returns&gt;String&lt;/returns&gt;
          public String GetComponentName()
          {
              return TypeDescriptor.GetComponentName(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetConverter
          /// &lt;/summary&gt;
          /// &lt;returns&gt;TypeConverter&lt;/returns&gt;
          public TypeConverter GetConverter()
          {
              return TypeDescriptor.GetConverter(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetDefaultEvent
          /// &lt;/summary&gt;
          /// &lt;returns&gt;EventDescriptor&lt;/returns&gt;
          public EventDescriptor GetDefaultEvent()
          {
              return TypeDescriptor.GetDefaultEvent(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetDefaultProperty
          /// &lt;/summary&gt;
          /// &lt;returns&gt;PropertyDescriptor&lt;/returns&gt;
          public PropertyDescriptor GetDefaultProperty()
          {
              return TypeDescriptor.GetDefaultProperty(this, true);
          }
  
          /// &lt;summary&gt;
          /// GetEditor
          /// &lt;/summary&gt;
          /// &lt;param name="editorBaseType"&gt;editorBaseType&lt;/param&gt;
          /// &lt;returns&gt;object&lt;/returns&gt;
          public object GetEditor(Type editorBaseType)
          {
              return TypeDescriptor.GetEditor(this, editorBaseType, true);
          }
  
          public EventDescriptorCollection GetEvents(Attribute[] attributes)
          {
              return TypeDescriptor.GetEvents(this, attributes, true);
          }
  
          public EventDescriptorCollection GetEvents()
          {
              return TypeDescriptor.GetEvents(this, true);
          }
  
          public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
          {
              PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];
              for (int i = 0; i &lt; this.Count; i++)
              {
                  CustomProperty prop = (CustomProperty)this[i];
                  newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);
              }
  
              return new PropertyDescriptorCollection(newProps);
          }
  
          public PropertyDescriptorCollection GetProperties()
          {
              return TypeDescriptor.GetProperties(this, true);
          }
  
          public object GetPropertyOwner(PropertyDescriptor pd)
          {
              return this;
          }
          #endregion
  
      }
  
      /// &lt;summary&gt;
      /// Custom property class 
      /// &lt;/summary&gt;
      public class CustomProperty
      {
          private string sName = string.Empty;
          private string sCategory = "";
          private bool bReadOnly = false;
          private bool bVisible = true;
          private object objValue = null;
  
          public CustomProperty(string sName, object value, Type type, bool bReadOnly, bool bVisible,string sCategory)
          {
              this.sName = sName;
              this.objValue = value;
              this.type = type;
              this.bReadOnly = bReadOnly;
              this.bVisible = bVisible;
              this.sCategory = sCategory;
          }
  
          private Type type;
          public Type Type
          {
              get { return type; }
          }
  
          public bool ReadOnly
          {
              get
              {
                  return bReadOnly;
              }
          }
  
          public string Name
          {
              get
              {
                  return sName;
              }
          }
  
          public string Category
          {
              get
              {
                  return sCategory;
              }
  
          }
  
  
          public bool Visible
          {
              get
              {
                  return bVisible;
              }
          }
  
          public object Value
          {
              get
              {
                  return objValue;
              }
              set
              {
                  objValue = value;
              }
          }
  
      }
  
  
      /// &lt;summary&gt;
      /// Custom PropertyDescriptor
      /// &lt;/summary&gt;
      public class CustomPropertyDescriptor : PropertyDescriptor
      {
          CustomProperty m_Property;
          public CustomPropertyDescriptor(ref CustomProperty myProperty, Attribute[] attrs) : base(myProperty.Name, attrs)
          {
              m_Property = myProperty;
          }
  
          #region PropertyDescriptor specific
  
          public override bool CanResetValue(object component)
          {
              return false;
          }
  
          public override Type ComponentType
          {
              get { return null; }
          }
  
          public override object GetValue(object component)
          {
              return m_Property.Value;
          }
  
          public override string Description
          {
              get { return m_Property.Name; }
          }
  
          public override string Category
          {
              get { return m_Property.Category; }
          }
  
          public override string DisplayName
          {
              get { return m_Property.Name; }
          }
  
          public override bool IsReadOnly
          {
              get { return m_Property.ReadOnly; }
          }
  
          public override void ResetValue(object component)
          {
              //Have to implement
          }
  
          public override bool ShouldSerializeValue(object component)
          {
              return false;
          }
  
          public override void SetValue(object component, object value)
          {
              m_Property.Value = value;
          }
  
          public override Type PropertyType
          {
              get { return m_Property.Type; }
          }
  
          #endregion
  
  
      }
  </code></pre>