如何在c#中本地化属性描述?

我正在开设一个将被其他国家的一些人使用的课程。 我必须将每条消息本地化,警告ec以便他们能够理解我们的意思。 在许多情况下,我实现了我的目标。 但是像描述这些属性属性在屁股上是如此痛苦。

这就是我现在所拥有的:

[Category("Editable Values"), Description("Sets the minimum select...")] public Ampere Simin { get {...} set {...} } 

 [Category("Editable Values"), Description(Localisation.Simin)] // "Localisation" here is the internal resource file that i wrote for messages, warnings, exceptions and -unfortunately- descriptions public Ampere Simin { get {...} set {...} } 

这就是我想要做的。 但是不可能以这种方式使用Localisations。 有关我可以使用的东西的任何建议而不是它吗?

子类:

 [STAThread] static void Main() { // just some example code to show it working in winforms, but // anything using System.ComponentModel should see the change Application.EnableVisualStyles(); Application.Run(new Form {Controls = {new PropertyGrid {Dock = DockStyle.Fill, SelectedObject = new Foo()}}}); } class Foo { // assume the following literals are keys, for example to a RESX [LocalizedCategory("cat")] [LocalizedDescription("desc")] [LocalizedDisplayName("disp name")] public string Bar { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Delegate | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter)] class LocalizedDescriptionAttribute : DescriptionAttribute { static string Localize(string key) { // TODO: lookup from resx, perhaps with cache etc return "Something for " + key; } public LocalizedDescriptionAttribute(string key) : base(Localize(key)) { } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event)] class LocalizedDisplayNameAttribute : DisplayNameAttribute { static string Localize(string key) { // TODO: lookup from resx, perhaps with cache etc return "Something for " + key; } public LocalizedDisplayNameAttribute(string key) : base(Localize(key)) { } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Delegate | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter)] class LocalizedCategoryAttribute : CategoryAttribute { public LocalizedCategoryAttribute(string key) : base(key) { } protected override string GetLocalizedString(string value) { // TODO: lookup from resx, perhaps with cache etc return "Something for " + value; } } 
 [Required(ErrorMessageResourceName = "LogOnModel_UserName_Required", ErrorMessageResourceType = typeof(Resources.Global))] [Display(Name = "LogOnModel_UserName_Required",resourceType = typeof(Resources.Global))] public string UserName { get; set; } 

请参阅: http : //geekswithblogs.net/shaunxu/archive/2010/05/06/localization-in-asp.net-mvc-ndash-3-days-investigation-1-day.aspx

我们来看看这个示例类:

 // ------------------------------------------------------------------------ public class Customer { // ---------------------------------------------------------------------- [Category( "Editable Values" ), LocDescription( "FirstName", "Sets the first name..." )] public string FirstName { get; set; } // ---------------------------------------------------------------------- [Category( "Editable Values" ), LocDescription( Key = "LastName", DefaultDescription = "Sets the last name..." )] public string LastName { get; set; } } // class Customer 

现在您可以实现自定义属性类:

 // ------------------------------------------------------------------------ public class LocDescriptionAttribute : DescriptionAttribute { // ---------------------------------------------------------------------- public LocDescriptionAttribute() { } // LocDescriptionAttribute // ---------------------------------------------------------------------- public LocDescriptionAttribute( string key, string defaultDescription ) : base( defaultDescription ) { Key = key; DefaultDescription = defaultDescription; } // LocDescriptionAttribute // ---------------------------------------------------------------------- public string Key { get; set; } // ---------------------------------------------------------------------- public string DefaultDescription { get; set; } // ---------------------------------------------------------------------- public override string Description { get { // load from resx string description = Strings.GetString( Key ); if ( string.IsNullOrEmpty( description ) ) { description = DefaultDescription; } return description; } } // Description } // class LocDescriptionAttribute 

现在您有了本地化描述:

 AttributeCollection attributes = TypeDescriptor.GetProperties( customer )[ "FirstName" ].Attributes; DescriptionAttribute myAttribute = (DescriptionAttribute)attributes[ typeof( DescriptionAttribute ) ]; ConsoleWiterLine( myAttribute.Description ); 

我结合了Marc Gravell和dsmith的答案:

首先:创建一个名为LocalizedDescriptionAttribute的Attribute类

 public class LocalizedDescriptionAttribute : DescriptionAttribute { static string Localize(string key) { return YourResourceClassName.ResourceManager.GetString(key); } public LocalizedDescriptionAttribute(string key) : base(Localize(key)) { } } 

将它用作LocalizedDescription(不需要“属性”一词)

 public class Foo { // myString is a key that exists in your Resources file [LocalizedDescription("myString")] public string Bar { get; set; } } 

Jani的回答略有扩展(对我来说效果很好):

 string description = Strings.GetString( Key ); 

可以更清楚地完成

 ResourceManager rm = YourResourceClassName.ResourceManager; string description = rm.GetString(Key); 

这含糊不清,但不清楚原始代码中缺少什么。 资源类的.ResourceManager属性是自动生成的。

然后,要访问它,请使用Glennular在此处描述的扩展方法: StackOverflow而不是字段/类名称中的硬编码(只使用LocDescriptionAttribute而不是DescriptionAttribute )。

我做的唯一其他调整是基于this IComparable enum使其静态,以允许任何枚举使用它而不是锁定到特定类型; 鉴于我无法应用界面将其限制为我添加了描述的枚举,这是我能做的最好的事情。

似乎CategoryAttribute具有基于内部资源查找本地化字符串的代码,但DescriptionAttribute没有本地化。

来自Reflector:

 public string Category { get { if (!this.localized) { this.localized = true; string localizedString = this.GetLocalizedString(this.categoryValue); if (localizedString != null) { this.categoryValue = localizedString; } } return this.categoryValue; } } 

我想你会扩展属性并创建自己的实现,传递ResourceType。 像这样的东西,模糊地基于DataAnnotation逻辑。 显然需要更多的清理。

 public class LocaleDescriptionAttribute : DescriptionAttribute { ... public LocaleDescriptionAttribute(string resourceKey, Type resourceType) : base(resourceKey) { this.resourceType = resourceType; } public override string Description { get { var description = base.Description; PropertyInfo property = resourceType.GetProperty( description, BindingFlags.Public | BindingFlags.Static); if (property == null) { return description; } return property.GetValue(null, null) as string; } } }