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
ItemsSource
pará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
ItemSource
uneMyEnumTypeValues
y seSelectedItem
une 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 empaquetarKeyValuePair
y 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.DescriptionAttribute
que 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
Converter
de enumeración a cadena.Mi forma favorita de hacer esto es con una de
ValueConverter
modo 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.
ValueDescription
es solo una clase simple con unaValue
propiedad y unaDescription
propiedad. Podrías usar fácilmente unTuple
conItem1
yItem2
, o unKeyValuePair
conKey
y enValue
lugar 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
ValueDescription
clase, laDescription
propiedad puede omitirse si no es necesaria. ¡Una clase simple con soloValue
propiedad también funciona!.Select(e => e.ToString())
, en lugar de usar laValueDescription
clase.ValueDescription
también seKeyValuePair
podrí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
DevExpress
respuesta 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
ComboBoxEdit
DevExpress sin algunas modificaciones.Primero, el XAML para
ComboBoxEdit
:No hace falta decir que deberá apuntar
xamlExtensions
al espacio de nombres que contiene la clase de extensión XAML (que se define a continuación):Y tenemos que señalar
myEnum
el 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 nuestroViewModel
para 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