Tuve el enlace de datos como este:

ItemsSource="{Binding Source={my:Enumeration {x:Type credit:OccupationCategory}}}"
                      DisplayMemberPath="Description"
                      SelectedValue="{Binding EmplType}"
                      SelectedValuePath="Value"/>

y funcionó realmente bien. Hacer un cambio en la más grande de diseño de software que ya no puedo tener todo lo que genera un INotifyPropertyChanged Evento, por lo que el tipo de enlace de datos no funciona. En cambio, yo manualmente la configuración de la selectedIndex y la construcción de las opciones de código como este:

ItemsSource="{Binding Source={StaticResource ResidenceOwnershipType}}"/>

que las referencias

<UserControl.Resources>
    <ObjectDataProvider x:Key="ResidenceOwnershipType" MethodName="GetValues" ObjectType="{x:Type System:Enum}" >
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="credit:ResidenceOwnershipType" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</UserControl.Resources>

Que funciona tan lejos como la construcción de la lista de opciones es que se trate y la vinculación de todos mis datos, pero no puedo obtener el comboboxes para mostrar la descripción de la etiqueta en la enumeración, en lugar de que el texto real.

He probado algo como esto:

DisplayMemberPath="Description"

pero eso no era correcto. ¿Cómo puedo hacer esto?

EDICIÓN:

Mi Enum:

[DataContract]
public enum ResidenceOwnershipType
{
    [Description("")]
    None = 0,
    [Description("Owns Home Outright")]
    OwnsHomeOutright = 1,
    [Description("Buying Home")]
    BuyingHome = 2,
    [Description("Renting/Leasing")] //Weird order here reflects RouteOne website
    RentingLeasing = 4,
    [Description("Living w/Relatives")]
    LivingWithRelatives = 3,
    [Description("Owns/Buying Mobile Home")]
    MobileHome = 5,
    [Description("Unknown")]
    Unknown = 6
}

2 Comentarios

  1. 13

    Si mantiene este ItemsSource se ha de definir una costumbre ItemTemplate como el DisplayMemberPath es sólo un camino a través de la cual usted no será capaz de recuperar la descripción.

    Por lo que la plantilla debería ser así: Se puede enlazar una TextBlock para el valor de enumeración (la actual DataContext) y de la tubería a través de una ValueConverter utilizando Binding.Converter. El código sería de reflexión para recuperar la Description (GetType, GetCustomAttributes etc.)

    Alternativas son un método personalizado que devolver una útil colección de inmediato (y se utiliza en la ObjectDataProvider) o una costumbre la extensión de marcado que hace lo mismo.


    Método de ejemplo, si estamos hablando de un ComponentModel.DescriptionAttribute:

    public static class EnumUtility
    {
        //Might want to return a named type, this is a lazy example (which does work though)
        public static object[] GetValuesAndDescriptions(Type enumType)
        {
            var values = Enum.GetValues(enumType).Cast<object>();
            var valuesAndDescriptions = from value in values
                                        select new
                                            {
                                                Value = value,
                                                Description = value.GetType()
                                                    .GetMember(value.ToString())[0]
                                                    .GetCustomAttributes(true)
                                                    .OfType<DescriptionAttribute>()
                                                    .First()
                                                    .Description
                                            };
            return valuesAndDescriptions.ToArray();
        }
    }
    <ObjectDataProvider x:Key="Data" MethodName="GetValuesAndDescriptions"
                        ObjectType="local:EnumUtility">
        <ObjectDataProvider.MethodParameters>
            <x:TypeExtension TypeName="local:TestEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    <ListBox ItemsSource="{Binding Source={StaticResource Data}}"
             DisplayMemberPath="Description"
             SelectedValuePath="Value"/>
    • No hay una manera de conseguir que la información con la ObjectDataProvider?
    • Sólo si se escribe un método que devuelve los objetos que contienen la descripción de la propiedad o simplemente la descripción de la cadena si que es todo lo que necesita, no iba a ser demasiado duro.
    • También se podría implementar esto como un Extensión de Marcado y la zanja de la ObjectDataProvider (personalizado extensiones de marcado son las soluciones a la mayoría de mis XAML problemas).
    • A partir de la lectura, se ve como la escritura de un método personalizado sería la mejor solución. Entonces yo podría reemplazar GetValues con GetValuesAndDescription o algo por el estilo. Yo realmente no sé cómo a pesar de que. Están lo suficientemente bien versado en la que usted podría dar un ejemplo?
    • Nunca se especifica lo que la descripción es, es en realidad un atributo de los valores enum?
    • Sí. He añadido la enumeración anterior. El antiguo enlace de datos lógica fue capaz de sacar y mostrar las descripciones. Permite que las cosas se vean mucho mejor de esa manera.
    • ¿Por qué no acaba de tomar el código de la anterior extensión de marcado, también, ¿por qué usted necesita para tirar eso de todos modos, no tiene sentido? (Ver editar por ejemplo, a pesar de que probablemente no hace nada diferente de la my:Enumeration extensión de marcado)
    • Que funcionó a la perfección! Gracias. Y tuve que tirar el viejo código porque hemos cambiado de un sistema local de datamodels a una API unificada. Tuve que rediseñar el enlace de datos basado en las limitaciones impuestas por el nuevo marco.

  2. 1

    Esta respuesta es una adición sobre el H. B. la respuesta que he implementado para mi propia aplicación:

    Comprobar si la Descripción atributo añadido:

    Description = (value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(true).OfType<DescriptionAttribute>().Count() > 0 ? 
                                                    value.GetType().GetMember(value.ToString())[0].GetCustomAttributes(true).OfType<DescriptionAttribute>().First().Description 
                                                    : value)

    Y Establecer el atributo siguiente para asegurarse de la correcta IDENTIFICACIÓN se utilizan: SelectedValuePath="Value"

Dejar respuesta

Please enter your comment!
Please enter your name here