Getting enum value through enum type

H

Harris

Dear all,

I have the following codes:

======

public enum Enum_Value
{
Value0 = 0,
Value1 = 10,
Value2 = 5,
Value3 = -1
}


private void comboImageType_SelectedIndexChanged(object sender,
System.EventArgs e)
{
setCombo(comboValue, typeof(Enum_Value));
}

private void setCombo(ComboBox combo, Type enumType)
{
object val;
Enum_Value enumValueObject;

//only do this if combo selection is valid
if (combo.SelectedIndex >= 0)
{
//Get element of Enum_Value pointed by selected index.
//So let say if SelectedIndex is 2 then I should get 5
val = Enum.GetValues(enumType).GetValue(combo.SelectedIndex);

//Assign back this value to enumValueObject
//enumValueObject = val; <-- ERROR : Cannot implicitly convert type
'object' to ...

enumValueObject = (Enum_Value ) val; // <--- is this is OK?

int iVal = (int) enumValueObject;
Console.Write("Enum value is " + iVal.ToString());
}
}

======

This really start as a question.. But while typing the question I got
some idea, try it and get it to work. So I might have already solve the
problem.

Basically I have to get enum value from ComboBox selected item. As you
can see above my problem is I try to assign object to enumValueObject .

So the question now is, am I doing the right thing? Perhaps there is
better way or shorter way of doing things?

Thanks in advance.
 
F

Fabio

Basically I have to get enum value from ComboBox selected item. As you
can see above my problem is I try to assign object to enumValueObject .

So the question now is, am I doing the right thing? Perhaps there is
better way or shorter way of doing things?

If I understand you can simply cast an enum value to and from an int type,
so you can do:

Enum_Type val = (Enum_Type)combo.SelectedIndex;

combo.SelectedIndex = (int)val;
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Enum_Type val = (Enum_Type)combo.SelectedIndex;

I do not think this may work, as the OP use not a consecutive numbering.

A possible solution:

enum_type val = Enum.GetValues( typeof(enum_type) )[ combo.SelectedIndex ];

Of course, this assume that the shown values are in teh same order they were
declared
 
H

Harris

Ignacio said:
Hi,

Enum_Type val = (Enum_Type)combo.SelectedIndex;

I do not think this may work, as the OP use not a consecutive numbering.

A possible solution:

enum_type val = Enum.GetValues( typeof(enum_type) )[ combo.SelectedIndex ];

My mistake here to use Enum_Type in place of Enum_Value in my
previous post. So might as well I correct this.

Enum_Value val = Enum.GetValues( typeof(enum_type) )[
combo.SelectedIndex ];

IMHO, This wont work because GetValues returnSystem.Array. The error is
: Cannot apply indexing with [] to an expression of type
'System.Array'.

Of course, this assume that the shown values are in teh same order they were
declared

Yes, the comboBox value is ordered same as Enum_Value ordered. For
instance combo box contents will be this

Value0
Value1
Value2
Value3

Thanks for all the help. Really appreciate it.
 
H

Harris

Here lies my latest dilemma :). I know that .Net is very flexible
langguage. So I always like to flex it and somewhat find it broken
point.

In summary my question is can I create and enum variable using enum
type?

Please read my inserted comments.
Dear all,

I have the following codes:

======

public enum Enum_Value
{
Value0 = 0,
Value1 = 10,
Value2 = 5,
Value3 = -1
}


private void comboImageType_SelectedIndexChanged(object sender,
System.EventArgs e)
{
setCombo(comboValue, typeof(Enum_Value));
}

private void setCombo(ComboBox combo, Type enumType)
{
object val;
Enum_Value enumValueObject;

I cannot do this becuase the enumObject may be of other type. Basically
what I want to do here is;

enumType enumValueObject;
// Error : The type or namespace name 'enumType'
// could not be found (are you missing a using directive
// or an assembly reference?)

//only do this if combo selection is valid
if (combo.SelectedIndex >= 0)
{
//Get element of Enum_Value pointed by selected index.
//So let say if SelectedIndex is 2 then I should get 5
val = Enum.GetValues(enumType).GetValue(combo.SelectedIndex);

//Assign back this value to enumValueObject
//enumValueObject = val; <-- ERROR : Cannot implicitly convert type
'object' to ...

enumValueObject = (Enum_Value ) val; // <--- is this is OK?

same here, because I am casting using Enum_Value which can be other
enum type.

So what I want to do here is something like this:

enumValueObject = (enumType ) val;
// Error : The type or namespace name 'enumType'
// could not be found (are you missing a using directive
// or an assembly reference?)

Come to think of it I get enumType by doing typeof(Enum_Value). So
enumType is not Enum_Value. But I can't think a way of getting back
Enum_Value out of enumType.

:) Any help is appreciated.
int iVal = (int) enumValueObject;
Console.Write("Enum value is " + iVal.ToString());
}
}

======

Thanks again.
 
B

Barry Kelly

There are at least 2 areas of confusion in your post:

(1) The values returned by Enum.GetValues() aren't necessarily in the
declared order.

(2) You don't need to cast an object to an enumeration value before
casting it to an integer in order to get the underlying integral value.

Perhaps you will find this example illustrating:

---8<---
using System;

enum Enum_Value
{
Value0 = 0,
Value1 = 10,
Value2 = 5,
Value3 = -1
}

public class App
{
static void Main()
{
foreach (string name in Enum.GetNames(typeof(Enum_Value)))
Console.WriteLine(name);
Console.WriteLine("---");
object x = Enum.GetValues(typeof(Enum_Value)).GetValue(2);
Console.WriteLine(x);
Console.WriteLine(x.GetType());
Console.WriteLine((int) x);
}
}
--->8---

It prints:

---8<---
Value0
Value2
Value1
Value3
---
Value1
Enum_Value
10
--->8---

-- Barry
 
H

Harris

Barry said:
There are at least 2 areas of confusion in your post:

(1) The values returned by Enum.GetValues() aren't necessarily in the
declared order.

Thanks, I dont realize this untill you point it out.

Fortunately my code so far do not depend on this since I do
Enum2Combo() and then later Combo2Enum(). So the order stay the same
during the process. My code is at the end of this post.
(2) You don't need to cast an object to an enumeration value before
casting it to an integer in order to get the underlying integral value.

Perhaps you will find this example illustrating:

I find it very illustrating :) . I have run this code changing Value3
to 1. It appeares that enum members are sorted according to their
value.

So if Value3 = 1. They are sorted to The ouput is

Value0 : 0
Value3 : 1
Value2 : 5
Value1 : 10

If Value3 = -1 and Value0 is -5

Value2 : 5
Value1 : 10
Value0 : -5
Value3 : -1

Beats me why it is sorted in such way. Ofcourse the bonus question is
whether they should be sorted at all. This is annoying.
---8<---
using System;

enum Enum_Value
{
Value0 = 0,
Value1 = 10,
Value2 = 5,
Value3 = -1
}

public class App
{
static void Main()
{
foreach (string name in Enum.GetNames(typeof(Enum_Value)))
Console.WriteLine(name);
Console.WriteLine("---");
object x = Enum.GetValues(typeof(Enum_Value)).GetValue(2);
Console.WriteLine(x);
Console.WriteLine(x.GetType());
Console.WriteLine((int) x);
}
}
--->8---

It prints:

---8<---
Value0
Value2
Value1
Value3
---
Value1
Enum_Value
10
--->8---

-- Barry


================

private enum Enum_Value
{
Value0 = 0,
Value1 = 10,
Value2 = 5,
Value3 = -1
}

private Enum_Value enumObject;

private void Form1_Load(object sender, System.EventArgs e)
{
Enum2Combo(comboBox1, typeof(Enum_Value), Enum_Value.Value3);
}

private object Combo2Enum(ComboBox combo, Type enumType)
{
if (combo.SelectedIndex >= 0)
{
try
{
return Enum.ToObject(
enumType,
(int)(Enum.GetValues(enumType).GetValue(combo.SelectedIndex)));
}
catch (Exception ex)
{
throw new Exception("Error setting enum from combo index. "
+ ex.Message, ex);
}
}

throw new Exception("Error setting enum due to invalid combo
index.");
}

private void Enum2Combo(ComboBox combo, Type enumType, object
defaultValue)
{
int i=0;
foreach(string itemName in Enum.GetNames(enumType))
{
combo.Items.Add(itemName.Replace("_"," "));
Console.WriteLine(defaultValue.ToString());

if (itemName == defaultValue.ToString())
combo.SelectedIndex = i;

i++;
}
}

private void button1_Click(object sender, System.EventArgs e)
{
enumObject = (Enum_Value) Combo2Enum(comboBox1, typeof(Enum_Value));
Console.WriteLine("---");
Console.WriteLine(enumObject.ToString() + " : " +
((int)enumObject).ToString());
}

================

It does look over kill :D. But I learn a lot about enum while doing the
code. At the same time I am still somewhat dissatisfied with this code.
If I ever change it to something else, I will post some update here.

:D Much ado about nothing.

Take care.
 
B

Bruce Wood

Here is my code for a combo box for enumerated values. Hope there's
something of value for you here.

using System;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;

namespace MyStuff.Controls
{
/// <summary>
/// A combo box that gives the user a choice between items
/// in an enumerated type. The combo
/// box offers auto-completion and sorting, and allows the
/// caller to interact purely in terms of enumerated values.
/// </summary>
/// <remarks>
/// Auto-completion is enabled only if the combo box's
/// <see cref="ComboBox.DropDownStyle"/> is <see
cref="ComboBoxStyle.DropDown"/>
/// or <see cref="ComboBoxStyle.Simple"/>.
/// </remarks>
public class ComboBoxForEnum : ComboBox
{
#region Delegate

/// <summary>
/// Delegate that converts the enumerated values to display strings.
/// </summary>
public delegate string EnumToDisplayStringDelegate(Enum enumValue);

#endregion

#region Private members

private Type _enumType;
private Enum[] _itemArray;
private EnumToDisplayStringDelegate _toDisplayString;
private Enum _noneValue;
private bool _displayNoneValue;

#endregion

#region Constructor

/// <summary>
/// Creates a new combo box with a <c>null</c> items collection,
/// and the default display member of <c>"Description"</c>.
/// </summary>
public ComboBoxForEnum()
{
this._enumType = null;
this._itemArray = null;
this._toDisplayString = null;
this._noneValue = null;
this._displayNoneValue = false;
}

#endregion

#region Public properties and methods for managing combo box items

/// <summary>
/// Gets or sets the enumerated type for which to populate the combo
box
/// with enumerated values.
/// </summary>
/// <value>A <see cref="Type"/> derived from <see cref="Enum"/>, or
/// <c>null</c> if the type has not yet been set.</value>
[Description("The enumerated type for which to populate the combo box
with enumerated values."), Category("Appearance"), DefaultValue(null)]
public Type EnumeratedType
{
get { return this._enumType; }
set
{
if (value == null)
{
if (this.DesignMode)
{
this._enumType = value;
}
else
{
throw new ArgumentNullException("value", "Enumerated type for
combo box cannot be null.");
}
}
else if (value.IsEnum)
{
this._enumType = value;
if (this._toDisplayString != null)
{
RebuildComboBoxContents();
}
}
else
{
throw new ArgumentException(String.Format("Type '{0}' is not an
enumerated type.", value), "value");
}
}
}

/// <summary>
/// Gets or sets a method that converts an enumerated value of type
/// <see cref="EnumeratedType"/> to a string to display in the combo
box.
/// </summary>
/// <value>A method that converts an enumerated value to a string,
/// or <c>null</c> if the method has not yet been set.</value>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public EnumToDisplayStringDelegate EnumToDisplayString
{
get { return this._toDisplayString; }
set
{
if (value == null)
{
throw new ArgumentNullException("value", "Display string
conversion method for combo box cannot be null.");
}
else
{
this._toDisplayString = value;
if (this._enumType != null)
{
RebuildComboBoxContents();
}
}
}
}

/// <summary>
/// Gets or sets the value that should be returned if the user
/// does not choose anything in the combo box.
/// </summary>
/// <value>An enumerated value of the type given by
/// <see cref="EnumeratedType"/>.</value>
[Description("The enumerated value that the combo box should return
if nothing is selected."), Category("Behavior"), DefaultValue(null)]
public Enum NoneValue
{
get { return this._noneValue; }
set
{
if (value == null)
{
this._noneValue = null;
RebuildComboBoxContents();
}
if (this._enumType == null)
{
throw new InvalidOperationException(String.Format("Attempt to set
'NoneValue' to '{0}' when 'EnumeratedType' has not yet been set.",
value));
}
else if (this._enumType.IsInstanceOfType(value))
{
this._noneValue = value;
RebuildComboBoxContents();
}
else
{
throw new ArgumentException(String.Format("Value '{0}' is not one
of the enumerations of type {1}.", value, this._enumType), "value");
}
}
}

/// <summary>
/// Gets or sets an indication of whether the combo box should
display the
/// <see cref="NoneValue"/> as one of the entries that the user can
choose.
/// Normally, the <see cref="NoneValue"/> represents a null choice by
the user
/// and is not represented in the list of valid choices. Callers may
want to
/// set this property to <c>true</c> in cases in which the <see
cref="NoneValue"/>
/// is a valid default value, rather than a value indicating "nothing
chosen."
/// </summary>
/// <value><c>true</c> if the combo box should display an entry
corresponding
/// to the <see cref="NoneValue"/>; <c>false</c> if the entry
/// corresponding to the <see cref="NoneValue"/> should be suppressed
/// and therefore the <see cref="NoneValue"/> is returned only when
there
/// is nothing selected in the combo box.</value>
[Description("Should the combo box display the NoneValue as one of
the items the user can choose?"), Category("Behavior"),
DefaultValue(false)]
public bool DisplayNoneValue
{
get { return this._displayNoneValue; }
set { this._displayNoneValue = value; }
}

/// <summary>
/// Gets or sets the currently selected enumerated value in the combo
box.
/// </summary>
/// <value>The enumerated value currently selected in the combo box,
or
/// <see cref="NoneValue"/> if there is currently nothing selected in
/// the combo box.</value>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Enum SelectedItem
{
get
{
int index = base.SelectedIndex;
if (this._itemArray == null)
{
if (this.DesignMode)
{
return null;
}
else
{
throw new InvalidOperationException("Attempt to fetch selected
item when combo box has not been properly initialized.");
}
}
else if (index < 0)
{
return this._noneValue;
}
else if (index < this._itemArray.Length)
{
return this._itemArray[index];
}
else
{
throw new Exception(String.Format("Combo box selected index was
{0}, but item array is only {2} items long.", index,
this._itemArray.Length));
}
}

set
{
if (this._itemArray == null)
{
if (!this.DesignMode)
{
throw new InvalidOperationException("Attempt to set selected item
when combo box has not been properly initialized.");
}
}
else
{
int index = 0;
while (index < this._itemArray.Length &&
!this._itemArray[index].Equals(value))
{
index += 1;
}
if (index >= this._itemArray.Length)
{
ClearSelection();
}
else
{
base.SelectedIndex = index;
}
}
}
}

/// <summary>
/// Clears the selection in the combo box back to a blank.
/// This methods selects entry -1 in the combo box, showing
/// blank contents.
/// </summary>
public void ClearSelection()
{
// If the combo box is the type that you can enter free text in,
then
// clear the text
if (base.DropDownStyle != ComboBoxStyle.DropDownList)
{
this.Text = "";
}

// Do it twice to get around a bug in .NET v1.1
base.SelectedIndex = -1;
base.SelectedIndex = -1;
}

#endregion

#region Private methods to populate combo box

/// <summary>
/// Rebuilds the combo box contents based on the current item array
and the current
/// display member.
/// </summary>
private void RebuildComboBoxContents()
{
base.Items.Clear();
if (this._enumType != null && this._toDisplayString != null)
{
Array enumArray = Enum.GetValues(this._enumType);
int displayLength = enumArray.Length;
if (!this._displayNoneValue && this._noneValue != null &&
Array.IndexOf(enumArray, this._noneValue) >= 0)
{
displayLength -= 1;
}
this._itemArray = new Enum[displayLength];
string[] displayArray = new string[displayLength];
int d = 0;
for (int i = 0; i < enumArray.Length; i++)
{
Enum enumValue = (Enum)enumArray.GetValue(i);
if (this._displayNoneValue || !enumValue.Equals(this._noneValue))
{
this._itemArray[d] = enumValue;
displayArray[d] = this._toDisplayString(enumValue);
d++;
}
}
if (base.Sorted)
{
Array.Sort(this._itemArray, displayArray);
}
base.Items.AddRange(displayArray);
}
}

#endregion
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top