Show Enum Description Instead of Name
Solution 1
If you keep this ItemsSource
you will have to define a custom ItemTemplate
as the DisplayMemberPath
is just a path via which you will not be able to retrieve the description.
As for what the template should look like: You can bind a TextBlock
to the enum value (the current DataContext
) and pipe that through a ValueConverter
using Binding.Converter
. The code would just be some reflection to retrieve the Description
(GetType
, GetCustomAttributes
etc.)
Alternatives are a custom method that return a usable collection right away (and is used in the ObjectDataProvider
) or a custom markup extension which does the same thing.
Method example if we are talking about a 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"/>
Solution 2
This answer is an addition on H.B.'s answer I implemented for my own application:
Check if the Description attribute is added:
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)
And Set the following attribute to make sure the correct ID's are used: SelectedValuePath="Value"
Nathan Tornquist
I am a full stack developer working in Chicago. I primarily develop for iOS and Node, but have a background in Ruby, Java, and C#. I dabble in hardware prototyping, and have a degree in Computer Engineering from Purdue. Outside of work, I enjoy playing the trumpet and reading novels.
Updated on June 07, 2022Comments
-
Nathan Tornquist almost 2 years
I had databinding set up like this:
ItemsSource="{Binding Source={my:Enumeration {x:Type credit:OccupationCategory}}}" DisplayMemberPath="Description" SelectedValue="{Binding EmplType}" SelectedValuePath="Value"/>
and it worked really well. Do to a change in the larger software design I can no longer have anything that generates an INotifyPropertyChanged Event so that type of databinding doesn't work. Instead I am manually setting the selectedIndex and building the options from code like this:
ItemsSource="{Binding Source={StaticResource ResidenceOwnershipType}}"/>
which references
<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>
That works as far as the building of the list options is concerned and the linking of all of my data, but I can't get the comboboxes to show the description tag in the enumeration instead of the actual text.
I've tried something like this:
DisplayMemberPath="Description"
but that wasn't correct. How would I go about doing this?
EDIT:
My 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 }