小编典典

DisplayNameAttribute的本地化

c#

我正在寻找一种本地化PropertyGrid中显示的属性名称的方法。使用DisplayNameAttribute属性可以将该属性的名称“覆盖”。不幸的是,属性不能具有非常量表达式。因此,我不能使用强类型资源,例如:

class Foo
{
   [DisplayAttribute(Resources.MyPropertyNameLocalized)]  // do not compile
   string MyProperty {get; set;}
}

我环顾四周,发现一些建议可以从DisplayNameAttribute继承来使用资源。我最终会得到如下代码:

class Foo
{
   [MyLocalizedDisplayAttribute("MyPropertyNameLocalized")] // not strongly typed
   string MyProperty {get; set;}
}

但是,我失去了强类型资源的好处,这绝对不是一件好事。然后我遇到了DisplayNameResourceAttribute,这可能是我想要的。但这应该在Microsoft.VisualStudio.Modeling.Design命名空间中,而我找不到应该为该命名空间添加的引用。

有人知道是否有一种简便的方法可以很好地实现DisplayName本地化?或者是否可以使用Microsoft似乎在Visual Studio中使用的方式?


阅读 438

收藏
2020-05-19

共1个答案

小编典典

这是我最终在单独的程序集中找到的解决方案(在我的情况下称为“ Common”):

   [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event)]
   public class DisplayNameLocalizedAttribute : DisplayNameAttribute
   {
      public DisplayNameLocalizedAttribute(Type resourceManagerProvider, string resourceKey)
         : base(Utils.LookupResource(resourceManagerProvider, resourceKey))
      {
      }
   }

用代码查找资源:

  internal static string LookupResource(Type resourceManagerProvider, string resourceKey)
  {
     foreach (PropertyInfo staticProperty in  resourceManagerProvider.GetProperties(BindingFlags.Static | BindingFlags.NonPublic))
     {
        if (staticProperty.PropertyType == typeof(System.Resources.ResourceManager))
        {
           System.Resources.ResourceManager resourceManager = (System.Resources.ResourceManager)staticProperty.GetValue(null, null);
           return resourceManager.GetString(resourceKey);
        }
     }

     return resourceKey; // Fallback with the key name
  }

典型用法是:

class Foo
{
      [Common.DisplayNameLocalized(typeof(Resources.Resource), "CreationDateDisplayName"),
      Common.DescriptionLocalized(typeof(Resources.Resource), "CreationDateDescription")]
      public DateTime CreationDate
      {
         get;
         set;
      }
}

当我使用文字字符串作为资源键时,这非常难看。使用常量将意味着修改Resources.Designer.cs,这可能不是一个好主意。

结论:我对此感到不满意,但对于Microsoft无法提供任何可用于此类常规任务的有用信息的情况,我甚至不满意。

2020-05-19