No post Enum ToString , é descrito um método para usar o atributo personalizado DescriptionAttribute
como este:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
E então, você chama uma função GetDescription
, usando sintaxe como:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Mas isso realmente não me ajuda quando quero simplesmente preencher uma ComboBox com os valores de uma enumeração, já que não posso forçar a chamada da ComboBoxGetDescription
.
O que eu quero tem os seguintes requisitos:
- A leitura
(HowNice)myComboBox.selectedItem
retornará o valor selecionado como o valor da enumeração. - O usuário deve ver as seqüências de exibição amigáveis, e não apenas o nome dos valores da enumeração. Então, em vez de ver "
NotNice
", o usuário verá "Not Nice At All
". - Felizmente, a solução exigirá alterações mínimas de código nas enumerações existentes.
Obviamente, eu poderia implementar uma nova classe para cada enumeração que criar e substituir a dela ToString()
, mas isso dá muito trabalho para cada enumeração e prefiro evitar isso.
Alguma ideia?
Heck, eu vou até dar um abraço como uma recompensa :-)
Respostas:
Você pode escrever um TypeConverter que leia os atributos especificados para procurá-los em seus recursos. Assim, você obteria suporte em vários idiomas para nomes de exibição sem muito aborrecimento.
Examine os métodos ConvertFrom / ConvertTo do TypeConverter e use a reflexão para ler atributos nos campos de enumeração .
fonte
ComboBox
tem tudo o que você precisa: aFormattingEnabled
propriedade para a qual você deve definirtrue
e oFormat
evento em que você precisará colocar a lógica de formatação desejada. Portanto,fonte
DataGridComboBoxColumn
pensamento. Alguma chance de resolvê-lo? Eu não sou capaz de encontrar uma maneira de obter acesso aoComboBox
doDataGridComboBoxColumn
.Não! Enums são primitivas e não objetos da interface do usuário - fazê-las servir a interface do usuário em .ToString () seria muito ruim do ponto de vista do design. Você está tentando resolver o problema errado aqui: o problema real é que você não deseja que Enum.ToString () apareça na caixa de combinação!
Agora, este é realmente um problema muito solucionável! Você cria um objeto de interface do usuário para representar seus itens de caixa de combinação:
E adicione apenas instâncias dessa classe à coleção Items da sua caixa de combinação e defina estas propriedades:
fonte
Dictionary
e usaram as propriedadesKey
eValue
comoDisplayMember
eValueMember
.TypeConverter. Eu acho que é isso que eu estava procurando. Todos saudam Simon Svensson !
Tudo o que preciso alterar na minha enumeração atual é adicionar esta linha antes da declaração.
Depois que eu fizer isso, qualquer enumeração será exibida usando os
DescriptionAttribute
campos.Ah, e o
TypeConverter
seria definido assim:Isso me ajuda com o meu caso ComboBox, mas obviamente não substitui o
ToString()
. Acho que vou me contentar com isso enquanto isso ...fonte
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, tentei fazerConsole.WriteLine(MyEnum.One)
e ele ainda sai como "One". Você precisa de alguma mágica especial comoTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(que funciona bem)?Usando seu exemplo de enumeração:
Crie uma extensão:
Então você pode usar algo como o seguinte:
Consulte: http://www.blackwasp.co.uk/EnumDescription.aspx para obter mais informações. O crédito vai para Richrd Carr pela solução
fonte
Você pode criar uma estrutura genérica que você pode usar para todas as suas enumerações com descrições. Com conversões implícitas de e para a classe, suas variáveis ainda funcionam como a enumeração, exceto para o método ToString:
Exemplo de uso:
fonte
Eu não acho que você pode fazer isso sem simplesmente vincular a um tipo diferente - pelo menos, não de forma conveniente. Normalmente, mesmo que você não possa controlar
ToString()
, você pode usar aTypeConverter
para formatar de forma personalizada - mas o IIRCSystem.ComponentModel
não respeita isso por enumerações.Você pode vincular a uma
string[]
das descrições ou a algo essencialmente como um par de chave / valor? (descrição / valor) - algo como:E depois vincular a
EnumWrapper<HowNice>.GetValues()
fonte
theComboBox.SelectItem
é o tipo deEnumWrapper<T>
, em vez deT
si mesmo. Eu acho que o scraimer querReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.A melhor maneira de fazer isso é fazer uma aula.
Eu acredito que é a melhor maneira de fazê-lo.
Quando colocado em caixas de combinação, o bonito ToString será mostrado, e o fato de que ninguém pode criar mais instâncias de sua classe torna-o um enum.
ps pode haver algumas pequenas correções de sintaxe, não sou muito bom com c #. (Cara de Java)
fonte
private HowNice(String desc) : base(desc) { }
e dos campos estáticos.Como você prefere não criar uma classe para cada enum, recomendo criar um dicionário do valor da enum / exibir o texto e vinculá-lo.
Observe que isso depende dos métodos do método GetDescription na postagem original.
fonte
Não é possível substituir o ToString () de enumerações em C #. No entanto, você pode usar métodos de extensão;
Claro que você terá que fazer uma chamada explícita para o método, ie;
Esta não é uma solução agradável, com uma instrução switch e tudo mais - mas deve funcionar e espero que sem muitas reescritas ...
fonte
A seguir à resposta do @scraimer, aqui está uma versão do conversor de tipo enum para string, que também suporta sinalizadores:
E um método de extensão para usá-lo:
fonte
Eu escreveria uma classe genérica para uso com qualquer tipo. Eu usei algo assim no passado:
Além disso, você pode adicionar um "método de fábrica" estático para criar uma lista de itens da caixa de combinação com um tipo de enumeração (praticamente o mesmo que o método GetDescriptions que você possui). Isso pouparia a necessidade de implementar uma entidade por cada tipo de enum e também forneceria um local agradável / lógico para o método auxiliar "GetDescriptions" (pessoalmente, eu chamaria FromEnum (T obj) ...
fonte
Crie uma coleção que contenha o que você precisa (como objetos simples que contêm uma
Value
propriedade que contém oHowNice
valor de enum e umaDescription
propriedade que contémGetDescription<HowNice>(Value)
e vincula o conjunto de dados a essa coleção.Um pouco assim:
quando você tem uma classe de coleção como esta:
Como você pode ver, essa coleção é facilmente personalizável com os lambda para selecionar um subconjunto do seu enumerador e / ou implementar uma formatação personalizada para, em
string
vez de usar aGetDescription<T>(x)
função mencionada.fonte
Você pode usar o PostSharp para direcionar o Enum.ToString e adicionar o código de adição que desejar. Isso não requer nenhuma alteração no código.
fonte
O que você precisa é transformar uma enumeração em um ReadonlyCollection e vincular a coleção à caixa de combinação (ou qualquer controle ativado por par de valor-chave).
Primeiro, você precisa de uma classe para conter os itens da lista. Como tudo o que você precisa é do par int / string, sugiro usar uma interface e uma combinação de classes base para que você possa implementar a funcionalidade em qualquer objeto que desejar:
Aqui está a interface e uma classe de amostra que a implementa. Observe que a chave 'da classe é fortemente digitada no Enum e que as propriedades IValueDescritionItem são implementadas explicitamente (para que a classe possa ter quaisquer propriedades e você pode ESCOLHER as que implementam o Par de chave / valor.
Agora a classe EnumToReadOnlyCollection:
Então, tudo que você precisa no seu código é:
Lembre-se de que sua coleção é digitada com MyItem, portanto o valor da caixa de combinação deve retornar um valor de enumeração se você vincular à propriedade apropriada.
Adicionei a propriedade T this [Enum t] para tornar a coleção ainda mais útil do que um simples consumível de combinação, por exemplo textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
É claro que você pode optar por transformar MyItem em uma classe Key / Value usada apenas para essa puprose, pulando efetivamente MyItem nos argumentos de tipo EnumToReadnlyCollection por completo, mas você será forçado a usar int para a chave (ou seja, obter a caixa de combinação1.SelectedValue retornaria int e não o tipo enum). Você pode contornar isso se criar uma classe KeyValueItem para substituir MyItem e assim por diante ...
fonte
Desculpe por ter esta discussão antiga.
Eu seguiria o caminho a seguir para localizar enum, pois ele pode exibir valores significativos e localizados para o usuário, não apenas a descrição, através de um campo de texto da lista suspensa neste exemplo.
Primeiro, eu crio um método simples chamado OwToStringByCulture para obter seqüências localizadas de um arquivo de recursos globais; neste exemplo, é BiBongNet.resx na pasta App_GlobalResources. Dentro desse arquivo de recurso, verifique se todas as strings são iguais aos valores da enumeração (ReallyNice, SortOfNice, NotNice). Nesse método, passo o parâmetro: resourceClassName, que geralmente é o nome do arquivo de recurso.
Em seguida, crio um método estático para preencher uma lista suspensa com enum como fonte de dados, chamada OwFillDataWithEnum. Este método pode ser usado com qualquer enum posteriormente.
Em seguida, na página com uma lista suspensa chamada DropDownList1, defina no Page_Load a seguinte linha de código simples para preencher a enumeração na lista suspensa.
É isso aí. Eu acho que com alguns métodos simples como esses, você pode preencher qualquer controle de lista com qualquer enumeração, não apenas com valores descritivos, mas também com texto localizado para exibição. Você pode fazer todos esses métodos como métodos de extensão para melhor uso.
Espero que esta ajuda. Compartilhe para ser compartilhado!
Aqui estão os métodos:
fonte
Para resolver isso, você deve usar um método de extensão e uma matriz de seqüências de caracteres da seguinte maneira:
Código simples e decodificação rápida.
fonte
Eu tentei essa abordagem e funcionou para mim.
Criei uma classe de wrapper para enumerações e sobrecarreguei o operador implícito para poder atribuí-la a variáveis de enumeração (no meu caso, tive que vincular um objeto a um
ComboBox
valor).Você pode usar a reflexão para formatar os valores enum da maneira que deseja, no meu caso, recupero o
DisplayAttribute
valores de enum (se existentes).Espero que isto ajude.
EDITAR:
Apenas no caso, eu uso a seguinte função para obter os
enum
valores que eu uso para oDataSource
doComboBox
fonte
Depois de ter o
GetDescription
método (ele precisa ser estático global), você poderá usá-lo através de um método de extensão:fonte
fonte
Você pode definir Enum como
e depois use
HowNice.GetStringValue()
.fonte