title: Setting the category of a property in the propertygrid in runtime
body: <p>I have a question for you. I would like to set the category attribute of some properties in my data class during runtime. My data class is autogenerated and I can't set the category during design time generation.</p>
  
  <p>I have used  the following to set the category of 2 properties during runtime, unfortunately when I set the category attribute for the second parameter is also changes the category of the first parameter again.... what am i missing?</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using System.Reflection;
  using System.Diagnostics;
  
  namespace myApplication
  {
    public partial class Form1 : Form
    {
      /// &lt;summary&gt;
      /// Required designer variable.
      /// &lt;/summary&gt;
      private System.ComponentModel.IContainer components = null;
  
      /// &lt;summary&gt;
      /// Clean up any resources being used.
      /// &lt;/summary&gt;
      /// &lt;param name="disposing"&gt;true if managed resources should be disposed; otherwise, false.&lt;/param&gt;
      protected override void Dispose(bool disposing)
      {
        if (disposing &amp;&amp; (components != null))
        {
          components.Dispose();
        }
        base.Dispose(disposing);
      }
  
      #region Windows Form Designer generated code
  
      /// &lt;summary&gt;
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// &lt;/summary&gt;
      private void InitializeComponent()
      {
        this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
        this.SuspendLayout();
        // 
        // propertyGrid1
        // 
        this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
        this.propertyGrid1.Name = "propertyGrid1";
        this.propertyGrid1.Size = new System.Drawing.Size(284, 262);
        this.propertyGrid1.TabIndex = 0;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.propertyGrid1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.Load += new System.EventHandler(this.Form1_Load);
        this.ResumeLayout(false);
  
      }
  
      #endregion
  
      private System.Windows.Forms.PropertyGrid propertyGrid1;
      public Form1()
      {
        InitializeComponent();
      }
  
      private void Form1_Load(object sender, EventArgs e)
      {
        Object selectedObject = new Shape()
          {
            x = 100,
            y = 200
          };
  
        var x = TypeDescriptor.GetProperties(selectedObject)["x"].Attributes;
        CategoryAttribute attrx = (CategoryAttribute)x[typeof(CategoryAttribute)] as CategoryAttribute;
  
        FieldInfo category_x = attrx.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
        if (category_x != null)
        {
          if (category_x.FieldType == "string".GetType())
          {
            category_x.SetValue(TypeDescriptor.GetProperties(selectedObject)["x"].Attributes[typeof(CategoryAttribute)], "A_Category_For_x");
          }
        }
  
        Debug.Assert(attrx.Category == "A_Category_For_x");
  
        var y = TypeDescriptor.GetProperties(selectedObject)["y"].Attributes;
        CategoryAttribute attry = (CategoryAttribute)y[typeof(CategoryAttribute)] as CategoryAttribute;
  
        FieldInfo category_y = attry.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
        if (category_y != null)
        {
          if (category_y.FieldType == "string".GetType())
          {
            category_y.SetValue(TypeDescriptor.GetProperties(selectedObject)["y"].Attributes[typeof(CategoryAttribute)], "A_Category_For_y");
          }
        }
  
        Debug.Assert(attrx.Category == "A_Category_For_x"); // here is stops... why is category for x changed????
        Debug.Assert(attry.Category == "A_Category_For_y");
  
  
  
        propertyGrid1.SelectedObject = selectedObject;
        // Force the PropertyGrid to redraw itself
        propertyGrid1.Refresh();
      }
  
    }
  
    public partial class Shape : System.ComponentModel.INotifyPropertyChanged
    {
      private short yField;
      private short xField;
  
      [System.Xml.Serialization.XmlAttributeAttribute()]
      public short y
      {
        get
        {
          return this.yField;
        }
        set
        {
          if ((this.yField != null))
          {
            if ((yField.Equals(value) != true))
            {
              this.yField = value;
              this.OnPropertyChanged("y");
            }
          }
          else
          {
            this.yField = value;
            this.OnPropertyChanged("y");
          }
        }
      }
  
  
      [System.Xml.Serialization.XmlAttributeAttribute()]
      public short x
      {
        get
        {
          return this.xField;
        }
        set
        {
          if ((this.xField != null))
          {
            if ((xField.Equals(value) != true))
            {
              this.xField = value;
              this.OnPropertyChanged("x");
            }
          }
          else
          {
            this.xField = value;
            this.OnPropertyChanged("x");
          }
        }
      }
  
      public event PropertyChangedEventHandler PropertyChanged;
  
      void OnPropertyChanged(string propertyName)
      {
        System.ComponentModel.PropertyChangedEventHandler handler = this.PropertyChanged;
        if ((handler != null))
        {
          handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
      }
    }
    static class Program
    {
      /// &lt;summary&gt;
      /// The main entry point for the application.
      /// &lt;/summary&gt;
      [STAThread]
      static void Main()
      {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
      }
    }
  }
  </code></pre>
  
  <p><strong>Update / extra information</strong>
  I think .net has the same instance for the CategoryAttribute when it not explicitly set. If i set it i can change the category per property like this:</p>
  
  <pre><code>    using System.ComponentModel;
      using System.Diagnostics;
      using System.Reflection;
      using System;
      using System.Linq;
  
      namespace CSharpConsoleApplication
      {
        public static class Program
        {
          public static void Main()
          {
            Object selectedObject = new myDataClass
            {
              x = 100,
              y = 200
            };
  
            CategoryAttribute attrx =
               selectedObject.GetType().GetProperty("x").GetCustomAttributes(typeof(CategoryAttribute), false).Single() as
               CategoryAttribute;
  
            FieldInfo category_x = attrx.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
            if (category_x != null)
            {
              if (category_x.FieldType == "string".GetType())
              {
                category_x.SetValue(attrx, "categoryX");
              }
            }
  
            Debug.Assert(attrx.Category == "categoryX");
  
            CategoryAttribute attry =
               selectedObject.GetType().GetProperty("y").GetCustomAttributes(typeof(CategoryAttribute), false).Single() as
               CategoryAttribute;
  
            FieldInfo category_y = attry.GetType().GetField("categoryValue", BindingFlags.NonPublic | BindingFlags.Instance);
            if (category_y != null)
            {
              if (category_y.FieldType == "string".GetType())
              {
                category_y.SetValue(attry, "categoryY");
              }
            }
  
            Debug.Assert(attrx.Category == "categoryX"); //success now!
            Debug.Assert(attry.Category == "categoryY");
          }
  
          public partial class myDataClass
          {
            [CategoryAttribute("Test")]
            public int x { get; set; }
  
            [CategoryAttribute("Default")]
            public int y { get; set; }
          }
        }
      }
  </code></pre>
  
  <p>As you can see this is succes! Unfortunately my partial class <em>myDataClass</em> is automaticly generated and i have to set the CategoryAttribute manually each time after generation. I don't want to do it like this but set it in runtime... </p>
  
  <p>May be this extra information can help??</p>