This is a migrated thread and some comments may be shown as answers.

Enumeration binding to a Combobox

4 Answers 525 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Pinho
Top achievements
Rank 1
Pinho asked on 24 Mar 2009, 10:57 AM
Hi,

 I've got a combobox that I will fill with the items set in an enumeration. To do this I'm using a helper:

 Copying and pasting the example in the page: Missing Enum.GetValues() when doing Silverlight for instance ?

 
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

    /// 
<summary> 
    /// Helper class to allow users to get the values of a enumeration 
    /// </summary> 
    public static class EnumHelper 
    { 
        /// <summary> 
        /// Get values of an enumeration of type T 
        /// </summary> 
        /// <typeparam name="T">Enumeration type</typeparam> 
        /// <returns>List of types in a enumeration</returns> 
        public static T[] GetValues<T>() 
        { 
            Type enumType = typeof(T); 
 
            if (!enumType.IsEnum) 
            { 
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 
            } 
 
            List<T> values = new List<T>(); 
 
            var fields = from field in enumType.GetFields() 
                         where field.IsLiteral 
                         select field; 
 
            foreach (FieldInfo field in fields) 
            { 
                object value = field.GetValue(enumType); 
                values.Add((T)value); 
            } 
 
            return values.ToArray(); 
        } 
 
        /// <summary> 
        /// Get all the values of an enumeration of Type enumType 
        /// </summary> 
        /// <param name="enumType">Enumeration type</param> 
        /// <returns>Array of objects</returns> 
        public static object[] GetValues(Type enumType) 
        { 
            if (!enumType.IsEnum) 
            { 
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 
            } 
 
            List<object> values = new List<object>(); 
 
            var fields = from field in enumType.GetFields() 
                         where field.IsLiteral 
                         select field; 
 
            foreach (FieldInfo field in fields) 
            { 
                object value = field.GetValue(enumType); 
                values.Add(value); 
            } 
 
            return values.ToArray(); 
        } 
    } 

The combo box items appear correctly with the value of the enumerator, but when I select one of its values, instead of the value, I get the index or key :(

 I tried to create a SelectionBoxItemTemplate but when I try to bind it I don't get any value, what am I doing wrong?

<telerikInput:RadComboBox.SelectionBoxItemTemplate> 
   <DataTemplate> 
     <TextBlock Text="{Binding Path=Value}"/> 
   </DataTemplate> 
</telerikInput:RadComboBox.SelectionBoxItemTemplate> 

Thanks to all,

L. Pinho


4 Answers, 1 is accepted

Sort by
0
Accepted
Miroslav
Telerik team
answered on 24 Mar 2009, 01:06 PM
Hi Luis,

Yes, this is a known issue for the Silverlight ItemsContol and happens in all ItemsControls. It internally converts the enum values to Int values, so you cannot use value converters or appropriate bindings to convert it.

One way to work around this is to have a custom wrapper class (something like boxing):

Here is how you can get the values and wrap them:

var enumType = typeof(HorizontalAlignment);  
 
var fields = from field in enumType.GetFields(BindingFlags.Static | BindingFlags.Public)  
             select new EnumViewModel(field.GetValue(null));  
 
comboBox.ItemsSource = fields;  
 

And the helper class:

public class EnumViewModel  
{  
    public EnumViewModel(object value)  
    {  
        this.EnumValue = value;  
        this.Name = value.ToString();  
    }  
 
    public object EnumValue  
    {  
        get;  
        set;  
    }  
 
    public String Name  
    {  
        get;  
        private set;  
    }  
 
    public override bool Equals(object obj)  
    {  
        return EnumValue.Equals(obj);  
    }  
 
    public override int GetHashCode()  
    {  
        return EnumValue.GetHashCode();  
    }  

Also if you are binding to a ViewModel that exposes a property with an enum value, you can implement a ValueConverter that will convert between the wrapper and the enum values. (You need the equals override for SelectedItem property to work)

Greetings,
Miroslav
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Pinho
Top achievements
Rank 1
answered on 26 Mar 2009, 12:32 PM
Hi Miroslav,

 thanks for the reply, after a few problems in the beggining I adapted some of your code and hints, and manage to do a "universal" class than I can use for all the enumerations without having to change the enumeration definition.

 If it helps anyone, I'm sharing the code:

    /// <summary> 
    /// Helper class to allow users to get the values of a enumeration 
    /// </summary> 
    public static class EnumHelper 
    { 
        /// <summary> 
        /// Get values of an enumeration of type T 
        /// </summary> 
        /// <typeparam name="T">Enumeration type</typeparam> 
        /// <returns>List of types in a enumeration</returns> 
        public static T[] GetValues<T>() 
        { 
            Type enumType = typeof(T); 
 
            if (!enumType.IsEnum) 
            { 
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 
            } 
 
            List<T> values = new List<T>(); 
 
            var fields = from field in enumType.GetFields() 
                         where field.IsLiteral 
                         select field; 
 
            foreach (FieldInfo field in fields) 
            { 
                object value = field.GetValue(enumType); 
                values.Add((T)value); 
            } 
 
            return values.ToArray(); 
        } 
 
        /// <summary> 
        /// Get all the values of an enumeration of Type enumType 
        /// </summary> 
        /// <param name="enumType">Enumeration type</param> 
        /// <returns>Array of objects</returns> 
        public static object[] GetValues(Type enumType) 
        { 
            if (!enumType.IsEnum) 
            { 
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 
            } 
 
            List<object> values = new List<object>(); 
 
            var fields = from field in enumType.GetFields() 
                         where field.IsLiteral 
                         select field; 
 
            foreach (FieldInfo field in fields) 
            { 
                object value = field.GetValue(enumType); 
                values.Add(value); 
            } 
 
            return values.ToArray(); 
        } 
 
        /// <summary> 
        /// Get a list of items inside a enumeration 
        /// </summary> 
        /// <param name="enumType">The enumeration type</param> 
        /// <returns>List of items Index, Value</returns> 
        public static List<EnumHelperItem> GetListOfItems(Type enumType) 
        { 
            List<EnumHelperItem> output = new List<EnumHelperItem>(); 
            if (!enumType.IsEnum) 
            { 
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); 
            } 
 
            var fields = from field in enumType.GetFields() 
                         where field.IsLiteral 
                         select field; 
 
            int i=0
            foreach (FieldInfo field in fields) 
            { 
                object value = field.GetValue(enumType); 
                output.Add(new EnumHelperItem(i, value)); 
                i++; 
            } 
 
            return output; 
        } 
 
    } 
 
    /// <summary> 
    /// Item helper 
    /// </summary> 
    public class EnumHelperItem : IValueConverter 
    { 
        int index; 
 
        /// <summary> 
        /// Index of the enumerator item 
        /// </summary> 
        public int Index 
        { 
            get { return index; } 
            set { index = value; } 
        } 
        object value; 
 
        /// <summary> 
        /// Value of the enumerator item 
        /// </summary> 
        public object Value 
        { 
            get { return this.value; } 
            set { this.value = value; } 
        } 
 
        /// <summary> 
        /// Default constructor 
        /// </summary> 
        public EnumHelperItem() 
        { } 
 
        /// <summary> 
        /// EnumHelperItem constructor 
        /// </summary> 
        /// <param name="index"></param> 
        /// <param name="value"></param> 
        public EnumHelperItem(int index, object value) 
        { 
            Index = index
            Value = value
        } 
 
        #region IValueConverter Members 
        /// <summary> 
        ///  
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="targetType"></param> 
        /// <param name="parameter"></param> 
        /// <param name="culture"></param> 
        /// <returns></returns
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        { 
            return value.ToString(); 
            //return ((EnumHelperItem)value).Value.ToString(); 
        } 
 
        /// <summary> 
        ///  
        /// </summary> 
        /// <param name="value"></param> 
        /// <param name="targetType"></param> 
        /// <param name="parameter"></param> 
        /// <param name="culture"></param> 
        /// <returns></returns
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        { 
            return Enum.Parse(targetType,((EnumHelperItem)value).Value.ToString(), false); 
        } 
        /// <summary> 
        ///  
        /// </summary> 
        /// <param name="obj"></param> 
        /// <returns></returns
        public override bool Equals(object obj) 
        { 
            if (this.Value != null && obj != null) 
                if (obj.GetType() == typeof(string)) 
                    return obj.ToString().Equals(this.Value.ToString()); 
                else if (obj.GetType() == typeof(EnumHelperItem)) 
                    return ((EnumHelperItem)obj).Value.ToString().Equals(this.Value.ToString()); 
                else 
                    return false; 
            else 
                return false; 
        } 
 
        /// <summary> 
        ///  
        /// </summary> 
        /// <returns></returns
        public override int GetHashCode() 
        { 
            return base.GetHashCode(); 
        } 
        #endregion 
    } 

The initial part of the code was retrieved from the site: Missing enum get values...

Usage example:

    <UserControl.Resources> 
        <ResourceDictionary> 
            <presutils:EnumHelperItem x:Key="EnumConverter"/> 
        </ResourceDictionary> 
    </UserControl.Resources> 
 
<telerikInput:RadComboBox x:Name="CmbStatus" SelectedItem="{Binding Path=BindProp, Mode=TwoWay, Converter={StaticResource EnumConverter}}"
            <telerikInput:RadComboBox.ItemTemplate> 
                <DataTemplate> 
                    <TextBlock Text="{Binding Path=Value}"></TextBlock> 
                </DataTemplate> 
            </telerikInput:RadComboBox.ItemTemplate> 
        </telerikInput:RadComboBox > 

List<EnumHelperItem> listOfEnumerations = EnumHelper.GetListOfItems(typeof(MyEnumeration)); 
CmbStatus.ItemsSource = listOfEnumerations

Thanks again and best regards,

L.Pinho



0
Riccardo
Top achievements
Rank 1
answered on 09 Nov 2009, 03:11 PM
If you don't want to use linq you can use this code:
public static T[] GetValues<T>()  
        {  
            Type enumType = typeof(T);  
 
            if (!enumType.IsEnum)  
            {  
                throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");  
            }  
 
            List<T> values = new List<T>();  
 
            FieldInfo[] fields = enumType.GetFields();  
 
            foreach (FieldInfo field in fields)  
            {  
                if (field.IsLiteral)  
                {  
                    object value = field.GetValue(enumType);  
                    values.Add((T)value);  
                }  
            }  
 
            return values.ToArray();  
        } 
0
Usame Esendir
Top achievements
Rank 1
answered on 01 Mar 2010, 02:25 PM
If you are using int value for binding it gives error, to solve the problem make sure your enum values are from 0 to n.
And then apply the following;

<telerik:RadComboBox x:Name="cmbVideoType" SelectedIndex="{Binding Type}" DisplayMemberPath="Value" /> 

List<EnumHelperItem> videoTypes = EnumHelper.GetListOfItems(typeof(VideoTypes));  
cmbVideoType.ItemsSource = videoTypes; 

Don't forget that Type binding is an integer value and your enum values must be from 0 to n, this is because of Index values of a container is from 0 to n.

Hope it helps.
Tags
ComboBox
Asked by
Pinho
Top achievements
Rank 1
Answers by
Miroslav
Telerik team
Pinho
Top achievements
Rank 1
Riccardo
Top achievements
Rank 1
Usame Esendir
Top achievements
Rank 1
Share this question
or