Como ejemplo, tome el siguiente código:
public enum ExampleEnum { FooBar, BarFoo }
public class ExampleClass : INotifyPropertyChanged
{
private ExampleEnum example;
public ExampleEnum ExampleProperty
{ get { return example; } { /* set and notify */; } }
}
Quiero un enlace de datos de la propiedad ExampleProperty a un ComboBox, para que muestre las opciones "FooBar" y "BarFoo" y funcione en modo TwoWay. De manera óptima, quiero que mi definición de ComboBox se vea así:
<ComboBox ItemsSource="What goes here?" SelectedItem="{Binding Path=ExampleProperty}" />
Actualmente tengo controladores para los eventos ComboBox.SelectionChanged y ExampleClass.PropertyChanged instalados en mi ventana donde hago el enlace manualmente.
¿Existe alguna forma canónica mejor o de algún tipo? ¿Usualmente usaría Convertidores y cómo llenaría el ComboBox con los valores correctos? Ni siquiera quiero comenzar con i18n en este momento.
Editar
Entonces, se respondió una pregunta: ¿Cómo lleno el ComboBox con los valores correctos?
Recupere los valores de Enum como una lista de cadenas a través de un ObjectDataProvider del método estático Enum.GetValues:
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="ExampleEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ExampleEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Esto lo puedo usar como ItemsSource para mi ComboBox:
<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"/>

Respuestas:
Puede crear una extensión de marcado personalizada.
Ejemplo de uso:
En la parte superior de tu XAML:
y entonces...
Y la implementación ...
fuente
ItemsSourceparámetro. Para mantener la vista y el modelo desacoplados, necesitaría crear una copia de la enumeración en ViewModel y codificar ViewModel para traducir entre los dos ... Lo que haría que la solución ya no sea tan simple. ¿O hay una manera de suministrar el tipo en sí desde ViewModel?En el modelo de vista puede tener:
En XAML, se
ItemSourceuneMyEnumTypeValuesy seSelectedItemune aSelectedMyEnumType.fuente
Prefiero no usar el nombre de enum en la interfaz de usuario. Prefiero usar un valor diferente para user (
DisplayMemberPath) y diferente para value (enum en este caso) (SelectedValuePath). Esos dos valores se pueden empaquetarKeyValuePairy almacenar en el diccionario.XAML
C#
EDITAR: Compatible con el patrón MVVM.
fuente
Enum.GetValues, pero eso no resolvería la parte de los nombres que se mostrarán. Al final, y especialmente si se implementa I18n, tendrá que cambiar manualmente las cosas si la enumeración cambia, de todos modos. Pero no se supone que las enumeraciones cambien a menudo, si es que lo hacen, ¿verdad? +1public Dictionary<ExampleEnum, string> ExampleEnumsWithCaptions { get; } = new Dictionary<ExampleEnum, string>() { {ExampleEnum.FooBar, "Foo Bar"}, {ExampleEnum.BarFoo, "Reversed Foo Bar"}, //{ExampleEnum.None, "Hidden in UI"}, };No sé si es posible solo en XAML, pero intente lo siguiente:
Dé un nombre a su ComboBox para que pueda acceder a él en el código detrás: "typesComboBox1"
Ahora intenta lo siguiente
fuente
Basado en la respuesta aceptada pero ahora eliminada proporcionada por ageektrapped , creé una versión reducida sin algunas de las características más avanzadas. Todo el código se incluye aquí para permitirle copiarlo y pegarlo y no ser bloqueado por link-rot.
Utilizo el
System.ComponentModel.DescriptionAttributeque realmente está destinado a descripciones de tiempo de diseño. Si no le gusta usar este atributo, puede crear el suyo propio, pero creo que usar este atributo realmente hace el trabajo. Si no usa el atributo, el nombre será por defecto el nombre del valor de enumeración en el código.Aquí está la clase utilizada como fuente de elementos:
Puedes usarlo en XAML así:
fuente
Utilice ObjectDataProvider:
y luego enlazar al recurso estático:
Encuentra esta solución en este blog
fuente
Converterde enumeración a cadena.Mi forma favorita de hacer esto es con una de
ValueConvertermodo que ItemsSource y SelectedValue se unan a la misma propiedad. Esto no requiere propiedades adicionales para mantener su ViewModel agradable y limpio.Y la definición del convertidor:
Este convertidor funcionará con cualquier enumeración.
ValueDescriptiones solo una clase simple con unaValuepropiedad y unaDescriptionpropiedad. Podrías usar fácilmente unTupleconItem1yItem2, o unKeyValuePairconKeyy enValuelugar de Valor y Descripción o cualquier otra clase de tu elección, siempre que pueda contener un valor de enumeración y una descripción de cadena de ese valor de enumeración.fuente
ValueDescriptionclase, laDescriptionpropiedad puede omitirse si no es necesaria. ¡Una clase simple con soloValuepropiedad también funciona!.Select(e => e.ToString()), en lugar de usar laValueDescriptionclase.ValueDescriptiontambién seKeyValuePairpodría usar a, como se muestra aquíAquí hay una solución genérica que utiliza un método auxiliar. Esto también puede manejar una enumeración de cualquier tipo subyacente (byte, sbyte, uint, long, etc.)
Método de ayuda:
Ver modelo:
Caja combo:
fuente
puedes considerar algo así:
defina un estilo para el bloque de texto o cualquier otro control que desee usar para mostrar su enumeración:
define tu estilo para ComboBoxItem
agregue un cuadro combinado y cárguelo con sus valores de enumeración:
Si su enumeración es grande, por supuesto, puede hacer lo mismo en el código, ahorrando mucho tipeo. Me gusta ese enfoque, ya que facilita la localización: define todas las plantillas una vez y luego solo actualiza los archivos de recursos de cadena.
fuente
Si está utilizando un MVVM, basado en la respuesta @rudigrobler, puede hacer lo siguiente:
Agregue la siguiente propiedad a la clase ViewModel
Luego, en XAML, haga lo siguiente:
fuente
Esta es una
DevExpressrespuesta específica basada en la respuesta más votada porGregor S.(actualmente tiene 128 votos).Esto significa que podemos mantener el estilo consistente en toda la aplicación:
Desafortunadamente, la respuesta original no funciona con un
ComboBoxEditDevExpress sin algunas modificaciones.Primero, el XAML para
ComboBoxEdit:No hace falta decir que deberá apuntar
xamlExtensionsal espacio de nombres que contiene la clase de extensión XAML (que se define a continuación):Y tenemos que señalar
myEnumel espacio de nombres que contiene la enumeración:Entonces, la enumeración:
El problema con el XAML es que no podemos usarlo
SelectedItemValue, ya que esto arroja un error ya que el configurador es inaccesible (un poco de supervisión por su parteDevExpress). Entonces tenemos que modificar nuestroViewModelpara obtener el valor directamente del objeto:Para completar, aquí está la extensión XAML de la respuesta original (ligeramente renombrada):
Descargo de responsabilidad: no tengo afiliación con DevExpress. Telerik es también una gran biblioteca.
fuente
Intenta usar
fuente
He creado un proyecto de código abierto de CodePlex que hace esto. Puede descargar el paquete NuGet desde aquí .
fuente