Я ищу способ локализовать имена свойств, отображаемые в 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?
источник
Ответы:
В .NET 4 есть атрибут Display из System.ComponentModel.DataAnnotations. Он работает в MVC 3
PropertyGrid
.Это ищет ресурс, названный
UserName
в вашемMyResources
RESX-файле.источник
typeof(MyResources)
, вам может потребоваться установить для модификатора доступа к файлу ресурсов значение Public .Мы делаем это для ряда атрибутов, чтобы поддерживать несколько языков. Мы использовали аналогичный подход к Microsoft, где они переопределяют свои базовые атрибуты и передают имя ресурса, а не фактическую строку. Затем имя ресурса используется для поиска в ресурсах DLL фактической строки, которую нужно вернуть.
Например:
При фактическом использовании атрибута вы можете пойти дальше и указать имена ресурсов как константы в статическом классе. Таким образом, вы получите объявления вроде.
Обновление
ResourceStrings
будет выглядеть примерно так (обратите внимание, каждая строка будет относиться к имени ресурса, который указывает фактическую строку):источник
[MyNamespace].[MyResourceFile].ResourceManager.GetString("MyString");
Вот решение, которое я получил в отдельной сборке (в моем случае она называется «Обычная»):
с кодом для поиска ресурса:
Типичное использование:
Что довольно уродливо, поскольку я использую буквальные строки для ключа ресурса. Использование константы там означало бы изменить Resources.Designer.cs, что, вероятно, не является хорошей идеей.
Заключение: меня это не устраивает, но еще меньше меня радует Microsoft, которая не может предоставить ничего полезного для такой типичной задачи.
источник
ResourceManager
свойств. Вместо этого вы можете просто получить свойство напрямую из типа, указанного в параметре:PropertyInfo property = resourceManagerProvider.GetProperty(resourceKey, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
Используя атрибут Display (из System.ComponentModel.DataAnnotations) и выражение nameof () в C # 6, вы получите локализованное и строго типизированное решение.
источник
Вы можете использовать T4 для генерации констант. Я написал один:
источник
Это старый вопрос, но я думаю, что это очень распространенная проблема, и вот мое решение в MVC 3.
Во-первых, шаблон T4 необходим для генерации констант, чтобы избежать неприятных строк. У нас есть файл ресурсов Labels.resx, в котором хранятся все строки меток. Поэтому шаблон T4 напрямую использует файл ресурсов,
Затем создается метод расширения для локализации DisplayName,
Атрибут DisplayName заменяется атрибутом DisplayLabel для автоматического чтения из Labels.resx,
После всех подготовительных работ пора коснуться атрибутов проверки по умолчанию. Я использую в качестве примера атрибут "Обязательный",
Теперь мы можем применить эти атрибуты в нашей модели,
По умолчанию имя свойства используется в качестве ключа для поиска «Label.resx», но если вы установите его с помощью «DisplayLabel», он будет использовать его.
источник
Вы можете создать подкласс DisplayNameAttribute для предоставления i18n, переопределив один из методов. Вот так. изменить: возможно, вам придется согласиться на использование константы для ключа.
источник
Я использую этот способ решения в моем случае
С кодом
источник
Ну сборка есть
Microsoft.VisualStudio.Modeling.Sdk.dll
. который поставляется с Visual Studio SDK (с пакетом интеграции Visual Studio).Но он будет использоваться почти так же, как ваш атрибут; невозможно использовать ресурсы строго типов в атрибутах просто потому, что они непостоянны.
источник
Прошу прощения за код VB.NET, мой C # немного заржавел ... Но вы поняли, верно?
Прежде всего, создайте новый класс:,
LocalizedPropertyDescriptor
который наследуетPropertyDescriptor
. ПереопределитеDisplayName
свойство следующим образом:Some.ResourceManager
- ResourceManager файла ресурсов, который содержит ваши переводы.Затем реализуйте
ICustomTypeDescriptor
в классе локализованные свойства и переопределитеGetProperties
метод:Теперь вы можете использовать атрибут DisplayName для хранения ссылки на значение в файле ресурсов ...
prop_description
- это ключ в файле ресурсов.источник