I am looking for a way to localize properties names displayed in a PropertyGrid. The property's name may be "overriden" using the DisplayNameAttribute attribute. Unfortunately attributes can not have non constant expressions. So I can not use strongly typed resources such as:
class Foo
{
[DisplayAttribute(Resources.MyPropertyNameLocalized)] // do not compile
string MyProperty {get; set;}
}
I had a look around and found some suggestion to inherit from DisplayNameAttribute to be able to use resource. I would end up up with code like:
class Foo
{
[MyLocalizedDisplayAttribute("MyPropertyNameLocalized")] // not strongly typed
string MyProperty {get; set;}
}
However I lose strongly typed resource benefits which is definitely not a good thing. Then I came across DisplayNameResourceAttribute which may be what I'm looking for. But it's supposed to be in Microsoft.VisualStudio.Modeling.Design namespace and I can't find what reference I am supposed to add for this namespace.
Anybody know if there's a easier way to achieve DisplayName localization in a good way ? or if there is as way to use what Microsoft seems to be using for Visual Studio ?
This is an old question, but I think this is a very common problem, and here is my solution in MVC 3.
Firstly, a T4 template is needed to generate constants to avoid nasty strings. We have a resource file ‘Labels.resx’ holds all the label strings. Therefore the T4 template uses the resource file directly,
Then, an extension method get created to localize the ‘DisplayName’,
‘DisplayName’ attribute is replaced by ‘DisplayLabel’ attribute in order to read from ‘Labels.resx’ automatically,
After all those preparation work, time to touch those default validation attributes. I am using ‘Required’ attribute as an example,
Now, We can apply those attributes in our model,
By default, property name is used as the key to look up ‘Label.resx’, but if you set it through ‘DisplayLabel’, it will use that instead.
We are doing this for a number of attributes in order to support multiple language. We have taken a similar approach to Microsoft, where they override their base attributes and pass a resource name rather than the actual string. The resource name is then used to perform a lookup in the DLL resources for the actual string to return.
For example:
You can take this a step further when actually using the attribute, and specify your resource names as constants in a static class. That way, you get declarations like.
Update
ResourceStrings
would look something like (note, each string would refer to the name of a resource that specifies the actual string):You could use T4 to generate constants. I wrote one:
Well, the assembly is
Microsoft.VisualStudio.Modeling.Sdk.dll
. which comes with the Visual Studio SDK (With Visual Studio Integration Package).But it would be used in pretty much the same way as your attribute; there is no way to use strongly types resources in attributes simply because they are not constant.
Using the Display attribute (from System.ComponentModel.DataAnnotations) and the nameof() expression in C# 6, you'll get a localized and strongly typed solution.
There is the Display attribute from System.ComponentModel.DataAnnotations in .NET 4. It works on the MVC 3
PropertyGrid
.This looks up a resource named
UserName
in yourMyResources
.resx file.