Estou procurando uma maneira de localizar nomes de propriedades exibidos em um PropertyGrid. O nome da propriedade pode ser "substituído" usando o atributo DisplayNameAttribute. Infelizmente, os atributos não podem ter expressões não constantes. Portanto, não posso usar recursos fortemente tipados, como:
class Foo
{
[DisplayAttribute(Resources.MyPropertyNameLocalized)] // do not compile
string MyProperty {get; set;}
}
Eu dei uma olhada e encontrei algumas sugestões para herdar de DisplayNameAttribute para poder usar o recurso. Eu acabaria com código como:
class Foo
{
[MyLocalizedDisplayAttribute("MyPropertyNameLocalized")] // not strongly typed
string MyProperty {get; set;}
}
No entanto, perco os benefícios de recursos fortemente tipados, o que definitivamente não é uma coisa boa. Então me deparei com DisplayNameResourceAttribute, que pode ser o que estou procurando. Mas ele deve estar no namespace Microsoft.VisualStudio.Modeling.Design e não consigo encontrar qual referência devo adicionar para esse namespace.
Alguém sabe se existe uma maneira mais fácil de obter a localização DisplayName de uma maneira boa? ou se existe como usar o que a Microsoft parece estar usando para o Visual Studio?
fonte
Respostas:
Existe o atributo Display de System.ComponentModel.DataAnnotations no .NET 4. Ele funciona no MVC 3
PropertyGrid
.Isso procura um recurso nomeado
UserName
no seuMyResources
arquivo .resx.fonte
typeof(MyResources)
, pode ser necessário definir seu modificador de acesso ao arquivo de recursos como Público .Estamos fazendo isso para vários atributos, a fim de suportar vários idiomas. Adotamos uma abordagem semelhante à Microsoft, onde eles substituem seus atributos básicos e passam um nome de recurso em vez da string real. O nome do recurso é usado para executar uma pesquisa nos recursos DLL para a seqüência real retornar.
Por exemplo:
Você pode dar um passo além ao usar o atributo e especificar os nomes dos recursos como constantes em uma classe estática. Dessa forma, você recebe declarações como.
A atualização
ResourceStrings
se pareceria com (observe que cada string se referiria ao nome de um recurso que especifica a string real):fonte
[MyNamespace].[MyResourceFile].ResourceManager.GetString("MyString");
Aqui está a solução que eu acabei em um assembly separado (chamado "Common" no meu caso):
com o código para procurar o recurso:
O uso típico seria:
O que é muito feio quando eu uso cadeias literais para a chave do recurso. O uso de uma constante significaria modificar o Resources.Designer.cs, o que provavelmente não é uma boa ideia.
Conclusão: Não estou satisfeito com isso, mas ainda menos com a Microsoft, que não pode fornecer nada de útil para uma tarefa tão comum.
fonte
ResourceManager
propriedades. Em vez disso, você pode simplesmente obter a propriedade diretamente do tipo fornecido no parâmetro:PropertyInfo property = resourceManagerProvider.GetProperty(resourceKey, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
Usando o atributo Display (de System.ComponentModel.DataAnnotations) e a expressão nameof () no C # 6, você obterá uma solução localizada e de tipo forte.
fonte
Você pode usar o T4 para gerar constantes. Eu escrevi um:
fonte
Essa é uma pergunta antiga, mas acho que esse é um problema muito comum, e aqui está minha solução no MVC 3.
Primeiramente, é necessário um modelo T4 para gerar constantes para evitar seqüências desagradáveis. Temos um arquivo de recurso 'Labels.resx' contém todas as seqüências de caracteres de rótulo. Portanto, o modelo T4 usa o arquivo de recurso diretamente,
Em seguida, um método de extensão é criado para localizar o 'DisplayName',
O atributo 'DisplayName' é substituído pelo atributo 'DisplayLabel' para ler automaticamente a partir de 'Labels.resx',
Depois de todo esse trabalho de preparação, é hora de tocar nesses atributos de validação padrão. Estou usando o atributo "Necessário" como exemplo,
Agora, podemos aplicar esses atributos em nosso modelo,
Por padrão, o nome da propriedade é usado como a chave para procurar 'Label.resx', mas se você o definir por meio de 'DisplayLabel', ele será usado.
fonte
Você pode subclassificar DisplayNameAttribute para fornecer i18n, substituindo um dos métodos. Igual a. editar: você pode ter que se contentar em usar uma constante para a chave.
fonte
Eu uso dessa maneira resolver no meu caso
Com o código
fonte
Bem, a montagem é
Microsoft.VisualStudio.Modeling.Sdk.dll
. que acompanha o Visual Studio SDK (com pacote de integração do Visual Studio).Mas seria usado da mesma maneira que o seu atributo; não há como usar recursos de tipos fortes em atributos simplesmente porque eles não são constantes.
fonte
Peço desculpas pelo código VB.NET, meu C # está um pouco enferrujado ... Mas você entendeu a ideia, certo?
Primeiro de tudo, crie uma nova classe
LocalizedPropertyDescriptor
:, que herdaPropertyDescriptor
. Substitua aDisplayName
propriedade assim:Some.ResourceManager
é o ResourceManager do arquivo de recurso que contém suas traduções.Em seguida, implemente
ICustomTypeDescriptor
na classe com as propriedades localizadas e substitua oGetProperties
método:Agora você pode usar o atributo 'DisplayName` para armazenar uma referência a um valor em um arquivo de recurso ...
prop_description
é a chave no arquivo de recurso.fonte