It’s pretty simple once you’ve seen the Solution:


    public class GlobalizedDescriptionAttribute :
        System.ComponentModel.DescriptionAttribute
    {
        String n;

        public GlobalizedDescriptionAttribute(string s) { n = s; }

        public override string Description {
            get {
                return Project.Properties.Resources.
                    ResourceManager.GetString(n);
            }
        }
    }

    public class GlobalizedDisplayNameAttribute :
        System.ComponentModel.DisplayNameAttribute
    {
        String n;

        public GlobalizedDisplayNameAttribute(string s) { n = s; }
       
        public override string DisplayName {
            get {
                return Project.Properties.Resources.
                    ResourceManager.GetString(n);
            }
        }
    }
 

You can then use those attributes with your objects properties:


    …
    [GlobalizedDisplayName("whatever")]
    [GlobalizedDescription("whateverthisdoes")]
    public int FooBar {
        get {}
        set {}
    }
    …
 

Globalizing the Category follows the same Pattern, extending CategoryAttribute.

There are some traps to avoid though:

  • Fetching the String in the Constructor does not seem to work.
  • If you use the Globalized…Attribute with an Identifier not in your Resources, the Program might throw OutOfMemoryExceptions at startup.