En la publicación Enum ToString , se describe un método para usar el atributo personalizado DescriptionAttribute
como este:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
Y luego, llamas a una función GetDescription
, usando una sintaxis como:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Pero eso realmente no me ayuda cuando simplemente quiero llenar un ComboBox con los valores de una enumeración, ya que no puedo forzar al ComboBox a llamarGetDescription
.
Lo que quiero tiene los siguientes requisitos:
- La lectura
(HowNice)myComboBox.selectedItem
devolverá el valor seleccionado como el valor de enumeración. - El usuario debe ver las cadenas de visualización fáciles de usar, y no solo el nombre de los valores de enumeración. Entonces, en lugar de ver "
NotNice
", el usuario vería "Not Nice At All
". - Con suerte, la solución requerirá cambios mínimos de código en las enumeraciones existentes.
Obviamente, podría implementar una nueva clase para cada enumeración que creo y anularla ToString()
, pero eso es mucho trabajo para cada enumeración, y prefiero evitar eso.
¿Algunas ideas?
Diablos, incluso te daré un abrazo como recompensa :-)
Respuestas:
Podría escribir un TypeConverter que lea los atributos especificados para buscarlos en sus recursos. Por lo tanto, obtendría soporte multilingüe para nombres de visualización sin mucha molestia.
Mire los métodos ConvertFrom / ConvertTo de TypeConverter y use la reflexión para leer los atributos en sus campos de enumeración .
fuente
ComboBox
tiene todo lo que necesita: laFormattingEnabled
propiedad, que debe establecertrue
y elFormat
evento, donde deberá colocar la lógica de formato deseada. Así,fuente
DataGridComboBoxColumn
. ¿Alguna oportunidad de resolverlo? No puedo encontrar una manera de acceder aComboBox
laDataGridComboBoxColumn
.No lo hagas Las enumeraciones son primitivas y no objetos de la interfaz de usuario; hacerlas servir a la interfaz de usuario en .ToString () sería bastante malo desde el punto de vista del diseño. Está intentando resolver el problema incorrecto aquí: ¡el problema real es que no desea que Enum.ToString () aparezca en el cuadro combinado!
Ahora bien, este es un problema muy solucionable. Crea un objeto de interfaz de usuario para representar los elementos del cuadro combinado:
Y luego simplemente agregue instancias de esta clase a la colección de elementos de su cuadro combinado y establezca estas propiedades:
fuente
Dictionary
y usaron las propiedadesKey
yValue
comoDisplayMember
yValueMember
.TypeConverter. Creo que esto es lo que estaba buscando. ¡Saluden a Simon Svensson !
Todo lo que necesito cambiar en mi enumeración actual es agregar esta línea antes de su declaración.
Una vez que haga eso, cualquier enumeración se mostrará utilizando
DescriptionAttribute
sus campos.Ah, y
TypeConverter
se definiría así:Esto me ayuda con mi caso ComboBox, pero obviamente no anula el
ToString()
. Supongo que me conformaré con esto mientras tanto ...fuente
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, intenté hacerloConsole.WriteLine(MyEnum.One)
y todavía sale como "Uno". ¿Necesitas magia especial comoTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(que funciona bien)?Usando su ejemplo de enumeración:
Crea una extensión:
Entonces puedes usar algo como lo siguiente:
Ver: http://www.blackwasp.co.uk/EnumDescription.aspx para más información. El crédito va a Richrd Carr por la solución
fuente
Podría crear una estructura genérica que podría usar para todas sus enumeraciones que tenga descripciones. Con conversiones implícitas hacia y desde la clase, sus variables aún funcionan como la enumeración, excepto por el método ToString:
Ejemplo de uso:
fuente
No creo que pueda hacerlo sin simplemente vincularse a un tipo diferente, al menos, no convenientemente. Normalmente, incluso si no puede controlar
ToString()
, puede usar unTypeConverter
para formatear de forma personalizada, pero IIRCSystem.ComponentModel
no respeta esto para las enumeraciones.¿Podría unirse a una
string[]
de las descripciones, o algo esencialmente como un par clave / valor? (descripción / valor) - algo como:Y luego unirse a
EnumWrapper<HowNice>.GetValues()
fuente
theComboBox.SelectItem
es un tipo deEnumWrapper<T>
, en lugar deT
sí mismo. Creo que scraimer quiereReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.La mejor manera de hacer esto es hacer una clase.
Creo que esa es la mejor manera de hacerlo.
Cuando se rellenan en cuadros combinados, se mostrará el bonito ToString, y el hecho de que nadie pueda hacer más instancias de su clase esencialmente lo convierte en una enumeración.
PD: es posible que deba haber algunas pequeñas correcciones de sintaxis, no soy muy bueno con C #. (Chico Java)
fuente
private HowNice(String desc) : base(desc) { }
y los campos estáticos.Dado que preferiría no crear una clase para cada enumeración, recomendaría crear un diccionario del valor de enumeración / texto de visualización y vincularlo en su lugar.
Tenga en cuenta que esto depende de los métodos del método GetDescription en la publicación original.
fuente
No es posible anular el ToString () de las enumeraciones en C #. Sin embargo, puede usar métodos de extensión;
Por supuesto, tendrá que hacer una llamada explícita al método, es decir;
Esta no es una buena solución, con una declaración de cambio y todo, pero debería funcionar y, con suerte, sin muchas reescrituras ...
fuente
Siguiendo con la respuesta @scraimer, aquí hay una versión del convertidor de tipo enum a string, que también admite indicadores:
Y un método de extensión para usarlo:
fuente
Escribiría una clase genérica para usar con cualquier tipo. He usado algo como esto en el pasado:
Además de esto, puede agregar un "método de fábrica" estático para crear una lista de elementos de cuadro combinado con un tipo de enumeración (más o menos lo mismo que el método GetDescriptions que tiene allí). Esto le ahorrará tener que implementar una entidad por cada tipo de enumeración, y también proporcionará un lugar agradable / lógico para el método auxiliar "GetDescriptions" (personalmente lo llamaría FromEnum (T obj) ...
fuente
Cree una colección que contenga lo que necesita (como objetos simples que contengan una
Value
propiedad que contenga elHowNice
valor de enumeración y unaDescription
propiedad que contengaGetDescription<HowNice>(Value)
y combine el combo con esa colección.Un poco como esto:
cuando tienes una clase de colección como esta:
Como puede ver, esta colección se puede personalizar fácilmente con lambda para seleccionar un subconjunto de su enumerador y / o implementar un formato personalizado en
string
lugar de usar laGetDescription<T>(x)
función que menciona.fuente
Puede usar PostSharp para apuntar a Enum.ToString y agregar el código adicional que desee. Esto no requiere ningún cambio de código.
fuente
Lo que necesita es convertir una enumeración en una colección ReadonlyCollection y vincular la colección al cuadro combinado (o cualquier control habilitado de par clave-valor para el caso)
En primer lugar, necesita una clase para contener los elementos de la lista. Dado que todo lo que necesita es el par int / string, sugiero usar una interfaz y un combo de clase base para que pueda implementar la funcionalidad en cualquier objeto que desee:
Aquí está la interfaz y una clase de muestra que lo implementa. Tenga en cuenta que la clave de la clase está fuertemente tipeada en la enumeración, y que las propiedades IValueDescritionItem se implementan explícitamente (por lo que la clase puede tener las propiedades y puede ELEGIR las que implementan Par clave / valor.
Ahora la clase EnumToReadOnlyCollection:
Entonces, todo lo que necesita en su código es:
Recuerde que su colección está escrita con MyItem, por lo que el valor del cuadro combinado debe devolver un valor de enumeración si se vincula a la propiedad apropiada.
Agregué la propiedad T this [Enum t] para hacer que la colección sea aún más útil que un simple consumible combinado, por ejemplo textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Por supuesto, puede optar por convertir MyItem en una clase Key / Value utilizada solo para este puprose omitiendo efectivamente MyItem en los argumentos de tipo de EnumToReadnlyCollection por completo, pero luego se vería obligado a ir con int para la clave (lo que significa obtener combobox1.SelectedValue devolvería int y no el tipo de enumeración). Evita eso si crea una clase KeyValueItem para reemplazar MyItem y así sucesivamente ...
fuente
Perdón por tener este viejo hilo.
Iría de la siguiente manera para localizar la enumeración, ya que puede mostrar valores significativos y localizados al usuario, no solo la descripción, a través de un campo de texto de lista desplegable en este ejemplo.
Primero, creo un método simple llamado OwToStringByCulture para obtener cadenas localizadas de un archivo de recursos globales, en este ejemplo es BiBongNet.resx en la carpeta App_GlobalResources. Dentro de este archivo de recursos, asegúrese de tener todas las cadenas iguales a los valores de la enumeración (ReallyNice, SortOfNice, NotNice). En este método, paso el parámetro: resourceClassName, que generalmente es el nombre del archivo de recursos.
A continuación, creo un método estático para llenar una lista desplegable con enum como fuente de datos, llamada OwFillDataWithEnum. Este método se puede usar con cualquier enumeración más adelante.
Luego, en la página con una lista desplegable llamada DropDownList1, configuré en Page_Load la siguiente línea de código simple para completar la enumeración de la lista desplegable.
Eso es. Creo que con algunos métodos simples como estos, puede llenar cualquier control de lista con cualquier enumeración, no solo con valores descriptivos sino con texto localizado para mostrar. Puede hacer todos estos métodos como métodos de extensión para un mejor uso.
Espero que esto ayude. ¡Comparte para compartir!
Aquí están los métodos:
fuente
Para resolver esto, debe usar un método de extensión y una matriz de cadenas de la siguiente manera:
Código simple y decodificación rápida.
fuente
Intenté este enfoque y funcionó para mí.
Creé una clase de contenedor para enumeraciones y sobrecargué el operador implícito para poder asignarlo a variables de enumeración (en mi caso tuve que vincular un objeto a un
ComboBox
valor).Puede usar la reflexión para formatear los valores de enumeración de la manera que desee, en mi caso recupero los
DisplayAttribute
valores de enumeración (si existen).Espero que esto ayude.
EDITAR:
Por si acaso, yo uso la siguiente función para obtener los
enum
valores que yo uso para elDataSource
de laComboBox
fuente
Una vez que tenga el
GetDescription
método (debe ser global estático), puede usarlo a través de un método de extensión:fuente
fuente
Puedes definir Enum como
y luego usar
HowNice.GetStringValue()
.fuente