<p>I am not sure whether is it possible to change attribute's parameter during runtime? For example, inside an assembly I have the following class</p>

<pre><code>public class UserInfo
{
    [Category("change me!")]
    public int Age
    {
        get;
        set;
    }
    [Category("change me!")]
    public string Name
    {
        get;
        set;
    }
}
</code></pre>

<p>This is a class that is provided by a third party vendor and <strong>I can't change the code</strong>. But now I found that the above descriptions are not accurate, and I want to change the "change me" category name to something else when i bind an instance of the above class to a property grid.</p>

<p>May I know how to do this?</p>

[{'answer_id': 51278, 'author': 'Glenn Slaven', 'author_id': 2975, 'author_profile': 'https://Stackoverflow.com/users/2975', 'pm_score': 0, 'selected': False, 'text': "<p>I really don't think so, unless there's some funky reflection that can pull it off.  The property decorations are set at compile time and to my knowledge are fixed</p>\n"}, {'answer_id': 51282, 'author': 'Glenn Slaven', 'author_id': 2975, 'author_profile': 'https://Stackoverflow.com/users/2975', 'pm_score': 5, 'selected': False, 'text': '<p>Well you learn something new every day, apparently I lied:</p>\n\n<blockquote>\n  <p>What isn’t generally realised is that\n  you can change attribute <strong>instance</strong> values fairly\n  easily at runtime. The reason is, of\n  course, that the instances of the\n  attribute classes that are created are\n  perfectly normal objects and can be\n  used without restriction. For example,\n  we can get the object:</p>\n\n<pre><code>ASCII[] attrs1=(ASCII[])\n    typeof(MyClass).GetCustomAttributes(typeof(ASCII), false);\n</code></pre>\n  \n  <p>…change the value of its public variable and show that it has changed:</p>\n\n<pre><code>attrs1[0].MyData="A New String";\nMessageBox.Show(attrs1[0].MyData);\n</code></pre>\n  \n  <p>…and finally create another instance\n  and show that its value is unchanged:</p>\n\n<pre><code>ASCII[] attrs3=(ASCII[])\n    typeof(MyClass).GetCustomAttributes(typeof(ASCII), false);\n MessageBox.Show(attrs3[0].MyData);\n</code></pre>\n</blockquote>\n\n<p><a href="http://www.vsj.co.uk/articles/display.asp?id=713" rel="noreferrer">http://www.vsj.co.uk/articles/display.asp?id=713</a></p>\n'}, {'answer_id': 276135, 'author': 'Bogdan Maxim', 'author_id': 23795, 'author_profile': 'https://Stackoverflow.com/users/23795', 'pm_score': 2, 'selected': False, 'text': '<p>Did you solve the problem?</p>\n\n<p>Here are possible steps to achieve an acceptable solution. </p>\n\n<ol>\n<li>Try to create a child class, redefine all of the properties that you need to change the <code>[Category]</code> attribute (mark them with <code>new</code>). Example:</li>\n</ol>\n\n<blockquote>\n<pre><code>public class UserInfo\n{\n [Category("Must change")]\n public string Name { get; set; }\n}\n\npublic class NewUserInfo : UserInfo\n{\n public NewUserInfo(UserInfo user)\n {\n // transfer all the properties from user to current object\n }\n\n [Category("Changed")]\n public new string Name {\nget {return base.Name; }\nset { base.Name = value; }\n }\n\npublic static NewUserInfo GetNewUser(UserInfo user)\n{\nreturn NewUserInfo(user);\n}\n}\n\nvoid YourProgram()\n{\nUserInfo user = new UserInfo();\n...\n\n// Bind propertygrid to object\n\ngrid.DataObject = NewUserInfo.GetNewUser(user);\n\n...\n\n}\n</code></pre>\n</blockquote>\n\n<p><strong>Later Edit:</strong> <em>This part of the solution is not workable if you have a large number of properties that you might need to rewrite the attributes. This is where part two comes into place:</em></p>\n\n<ol start="2">\n<li>Of course, this won\'t help if the class is not inheritable, or if you have a lot of objects (and properties). You would need to create a full automatic proxy class that gets your class and creates a dynamic class, applies attributes and of course makes a connection between the two classes.. This is a little more complicated, but also achievable. Just use reflection and you\'re on the right road.</li>\n</ol>\n'}, {'answer_id': 1152895, 'author': 'Bogdan Maxim', 'author_id': 23795, 'author_profile': 'https://Stackoverflow.com/users/23795', 'pm_score': 0, 'selected': False, 'text': '<p>In the mean time I\'ve come to a partial solution, derived from the following articles:</p>\n\n<ol>\n<li><a href="http://msdn.microsoft.com/en-us/magazine/cc163816.aspx" rel="nofollow noreferrer">ICustomTypeDescriptor, Part 1</a></li>\n<li><a href="http://msdn.microsoft.com/en-us/magazine/cc163804.aspx" rel="nofollow noreferrer">ICustomTypeDescriptor, Part 2</a></li>\n<li><a href="http://www.codeproject.com/KB/tabs/Dynamic_Propertygrid.aspx" rel="nofollow noreferrer">Add (Remove) Items to (from) PropertyGrid at Runtime</a></li>\n</ol>\n\n<p>Basically you would create a generic class <code>CustomTypeDescriptorWithResources&lt;T&gt;</code>, that would get the properties through reflection and load <code>Description</code> and <code>Category</code> from a file (I suppose you need to display localized text so you could use a resources file (<code>.resx</code>))</p>\n'}, {'answer_id': 1839628, 'author': 'Marc Gravell', 'author_id': 23354, 'author_profile': 'https://Stackoverflow.com/users/23354', 'pm_score': 2, 'selected': False, 'text': '<p>You can subclass most of the common attributes quite easily to provide this extensibility:</p>\n\n<pre><code>using System;\nusing System.ComponentModel;\nusing System.Windows.Forms;\nclass MyCategoryAttribute : CategoryAttribute {\n    public MyCategoryAttribute(string categoryKey) : base(categoryKey) { }\n\n    protected override string GetLocalizedString(string value) {\n        return "Whad\'ya know? " + value;\n    }\n}\n\nclass Person {\n    [MyCategory("Personal"), DisplayName("Date of Birth")]\n    public DateTime DateOfBirth { get; set; }\n}\n\nstatic class Program {\n    [STAThread]\n    static void Main() {\n        Application.EnableVisualStyles();\n        Application.Run(new Form { Controls = {\n           new PropertyGrid { Dock = DockStyle.Fill,\n               SelectedObject = new Person { DateOfBirth = DateTime.Today}\n           }}});\n    }\n}\n</code></pre>\n\n<p>There are more complex options that involve writing custom <code>PropertyDescriptor</code>s, exposed via <code>TypeConverter</code>, <code>ICustomTypeDescriptor</code> or <code>TypeDescriptionProvider</code> - but that is usually overkill.</p>\n'}, {'answer_id': 2114049, 'author': 'Jules', 'author_id': 120399, 'author_profile': 'https://Stackoverflow.com/users/120399', 'pm_score': 3, 'selected': False, 'text': '<p>In case anyone else walks down this avenue, the answer is you can do it, with reflection, except you can\'t because there\'s a bug in the framework. Here\'s how you would do it:</p>\n\n<pre><code>Dim prop As PropertyDescriptor = TypeDescriptor.GetProperties(GetType(UserInfo))("Age")\nDim att As CategoryAttribute = DirectCast(prop.Attributes(GetType(CategoryAttribute)), CategoryAttribute)\nDim cat As FieldInfo = att.GetType.GetField("categoryValue", BindingFlags.NonPublic Or BindingFlags.Instance)\ncat.SetValue(att, "A better description")\n</code></pre>\n\n<p>All well and good, except that the category attribute is changed for all the properties, not just \'Age\'.</p>\n'}, {'answer_id': 10541471, 'author': 'David MacDermot', 'author_id': 1388044, 'author_profile': 'https://Stackoverflow.com/users/1388044', 'pm_score': 1, 'selected': False, 'text': '<p>Given that the PropertyGrid\'s selected item is "Age":</p>\n\n<pre><code>SetCategoryLabelViaReflection(MyPropertyGrid.SelectedGridItem.Parent,\n    MyPropertyGrid.SelectedGridItem.Parent.Label, "New Category Label");\n</code></pre>\n\n<p>Where <code>SetCategoryLabelViaReflection()</code> is defined as follows:</p>\n\n<pre><code>private void SetCategoryLabelViaReflection(GridItem category,\n                                           string oldCategoryName,\n                                           string newCategoryName)\n{\n    try\n    {\n        Type t = category.GetType();\n        FieldInfo f = t.GetField("name",\n                                 BindingFlags.NonPublic | BindingFlags.Instance);\n        if (f.GetValue(category).Equals(oldCategoryName))\n        {\n            f.SetValue(category, newCategoryName);\n        }\n    }\n    catch (Exception ex)\n    {\n        System.Diagnostics.Trace.Write("Failed Renaming Category: " + ex.ToString());\n    }\n}\n</code></pre>\n\n<p>As far as programatically setting the selected item, the parent category of which you wish to change; there are a number of simple solutions.  Google "Set Focus to a specific PropertyGrid property".</p>\n'}, {'answer_id': 19787957, 'author': 'mmm', 'author_id': 2922477, 'author_profile': 'https://Stackoverflow.com/users/2922477', 'pm_score': -1, 'selected': False, 'text': '<p>You can change Attribute values at runtime at Class level (not object):</p>\n\n<pre><code>var attr = TypeDescriptor.GetProperties(typeof(UserContact))["UserName"].Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;\nattr.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(attr, username_readonly);\n</code></pre>\n'}, {'answer_id': 25254059, 'author': 'Darien Pardinas', 'author_id': 1416294, 'author_profile': 'https://Stackoverflow.com/users/1416294', 'pm_score': 2, 'selected': False, 'text': '<p>Unfortunately attributes are not meant to change at runtime. You basically have two options:</p>\n\n<ol>\n<li><p>Recreate a similar type on the fly using <code>System.Reflection.Emit</code> as shown below.</p></li>\n<li><p>Ask your vendor to add this functionality. If you are using Xceed.WpfToolkit.Extended you can download the source code from <a href="https://wpftoolkit.codeplex.com/SourceControl/latest" rel="nofollow">here</a> and easily implement an interface like <code>IResolveCategoryName</code> that would resolve the attribute at runtime. I did a bit more than that, it was pretty easy to add more functionality like limits when editing a numeric value in a <code>DoubleUpDown</code> inside the <code>PropertyGrid</code>, etc.</p>\n\n<pre><code>namespace Xceed.Wpf.Toolkit.PropertyGrid\n{\n    public interface IPropertyDescription\n    {\n        double MinimumFor(string propertyName);\n        double MaximumFor(string propertyName);\n        double IncrementFor(string propertyName);\n        int DisplayOrderFor(string propertyName);\n        string DisplayNameFor(string propertyName);\n        string DescriptionFor(string propertyName);\n        bool IsReadOnlyFor(string propertyName);\n    }\n}\n</code></pre></li>\n</ol>\n\n<p>For first option: This however lack of proper property binding to reflect the result back to the actual object being edited.</p>\n\n<pre><code>    private static void CreatePropertyAttribute(PropertyBuilder propertyBuilder, Type attributeType, Array parameterValues)\n    {\n        var parameterTypes = (from object t in parameterValues select t.GetType()).ToArray();\n        ConstructorInfo propertyAttributeInfo = typeof(RangeAttribute).GetConstructor(parameterTypes);\n        if (propertyAttributeInfo != null)\n        {\n            var customAttributeBuilder = new CustomAttributeBuilder(propertyAttributeInfo,\n                parameterValues.Cast&lt;object&gt;().ToArray());\n            propertyBuilder.SetCustomAttribute(customAttributeBuilder);\n        }\n    }\n    private static PropertyBuilder CreateAutomaticProperty(TypeBuilder typeBuilder, PropertyInfo propertyInfo)\n    {\n        string propertyName = propertyInfo.Name;\n        Type propertyType = propertyInfo.PropertyType;\n\n        // Generate a private field\n        FieldBuilder field = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);\n\n        // Generate a public property\n        PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType,\n            null);\n\n        // The property set and property get methods require a special set of attributes:\n        const MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;\n\n        // Define the "get" accessor method for current private field.\n        MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, getSetAttr, propertyType, Type.EmptyTypes);\n\n        // Intermediate Language stuff...\n        ILGenerator currGetIl = currGetPropMthdBldr.GetILGenerator();\n        currGetIl.Emit(OpCodes.Ldarg_0);\n        currGetIl.Emit(OpCodes.Ldfld, field);\n        currGetIl.Emit(OpCodes.Ret);\n\n        // Define the "set" accessor method for current private field.\n        MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, getSetAttr, null, new[] { propertyType });\n\n        // Again some Intermediate Language stuff...\n        ILGenerator currSetIl = currSetPropMthdBldr.GetILGenerator();\n        currSetIl.Emit(OpCodes.Ldarg_0);\n        currSetIl.Emit(OpCodes.Ldarg_1);\n        currSetIl.Emit(OpCodes.Stfld, field);\n        currSetIl.Emit(OpCodes.Ret);\n\n        // Last, we must map the two methods created above to our PropertyBuilder to \n        // their corresponding behaviors, "get" and "set" respectively. \n        property.SetGetMethod(currGetPropMthdBldr);\n        property.SetSetMethod(currSetPropMthdBldr);\n\n        return property;\n\n    }\n\n    public static object EditingObject(object obj)\n    {\n        // Create the typeBuilder\n        AssemblyName assembly = new AssemblyName("EditingWrapper");\n        AppDomain appDomain = System.Threading.Thread.GetDomain();\n        AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.Run);\n        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assembly.Name);\n\n        // Create the class\n        TypeBuilder typeBuilder = moduleBuilder.DefineType("EditingWrapper",\n            TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass |\n            TypeAttributes.BeforeFieldInit, typeof(System.Object));\n\n        Type objType = obj.GetType();\n        foreach (var propertyInfo in objType.GetProperties())\n        {\n            string propertyName = propertyInfo.Name;\n            Type propertyType = propertyInfo.PropertyType;\n\n            // Create an automatic property\n            PropertyBuilder propertyBuilder = CreateAutomaticProperty(typeBuilder, propertyInfo);\n\n            // Set Range attribute\n            CreatePropertyAttribute(propertyBuilder, typeof(Category), new[]{"My new category value"});\n\n        }\n\n        // Generate our type\n        Type generetedType = typeBuilder.CreateType();\n\n        // Now we have our type. Let\'s create an instance from it:\n        object generetedObject = Activator.CreateInstance(generetedType);\n\n        return generetedObject;\n    }\n}\n</code></pre>\n'}, {'answer_id': 41679916, 'author': 'mbomb007', 'author_id': 2415524, 'author_profile': 'https://Stackoverflow.com/users/2415524', 'pm_score': 1, 'selected': False, 'text': '<p>Here\'s a "cheaty" way to do it: </p>\n\n<p>If you have a fixed number of constant potential values for the attribute parameter, you can define a separate property for each potential value of the parameter (and give each property that slightly different attribute), then switch which property you reference dynamically.</p>\n\n<p>In VB.NET, it might look like this:</p>\n\n<pre class="lang-vb prettyprint-override"><code>Property Time As Date\n\n&lt;Display(Name:="Month")&gt;\nReadOnly Property TimeMonthly As Date\n    Get\n        Return Time\n    End Get\nEnd Property\n\n&lt;Display(Name:="Quarter")&gt;\nReadOnly Property TimeQuarterly As Date\n    Get\n        Return Time\n    End Get\nEnd Property\n\n&lt;Display(Name:="Year")&gt;\nReadOnly Property TimeYearly As Date\n    Get\n        Return Time\n    End Get\nEnd Property\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/51269', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3834/']