Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
4165
Column Editor using Enum as a DataSource
posted

Hello,

This is a bit of a complicated questions, so hopefully I will cover all bases:

Take this simple object, that has a string and enum as properties

public class Calculation

{

public string Name {get;set;}

public CalculationType CalculationType {get;set;

}

public enum CalculationType

{

[Description("<")]
Less_Than = 0,

[Description(">")]
Greater_Than = 1,

[Description("=")]
Equal = 2,

[Description("<=")]
Less_Than_Equal_To = 3,

[Description(">=")]
Greater_Than_Equal_To = 4,

[Description("<>")]
Not_Equal_To = 5

}

We are going to set a list of these to ultragrid datasource.

In the initialize event of the data grid, we are setting the editor for the CalculationType to be an UltraComboEditor. We want the datasource of the UltraComboEditor to be the enum CalculationType.

We have two extension methods for enum. One that handles straight conversion of an enum to dictionary (so that it can be ToList for combo datasource) and another that handles conversion with the description attribute.

public static IDictionary<int, string> ToDictionaryWithDescriptions(this Type type)
{
if (!type.IsEnum)
{
throw new InvalidCastException("'enumValue' is not an Enumeration!");
}

var names = Enum.GetNames(type);
var values = Enum.GetValues(type);

return Enumerable.Range(0, names.Length)
.Select(index => new
{
Key = (int)(object)((Enum)values.GetValue(index)),
Value = ((Enum)values.GetValue(index)).GetDescription(),

})
.ToDictionary(k => k.Key, k => k.Value);
}

public static IDictionary<int, string> ToDictionary<T>(this Type type)
{
if (!type.IsEnum)
{
throw new InvalidCastException("'enumValue' is not an Enumeration!");
}

return Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(t => (int)(object)t, t => t.ToString());
}

We then have extension methods for combo editor. Note GridKey is simple class with two string, Key/Value. I thought for some reason we could not use anonymous. 

public static void SetDataSource<T>(this UltraComboEditor editor)
{
editor.DataSource = typeof(T).ToDictionary<T>().Select(
list => new GridKeyValue { Value = list.Key.ToString(), Key = list.Value }).ToList();

editor.ValueMember = "Value";
editor.DisplayMember = "Key";
}

public static void SetDataSourceWithDescriptions<T>(this UltraComboEditor editor)
{
editor.DataSource = typeof(T).ToDictionaryWithDescriptions().Select(
list => new { list.Key, list.Value }).ToList();

editor.ValueMember = "Key";
editor.DisplayMember = "Value";
}

Here is an example of how we are setting in grid combo editor

...

  ColumnsCollection c = e.Layout.Bands[0].Columns;

if (ucmboComputeOperator == null)
{
ucmboComputeOperator = new UltraComboEditor
{
DropDownStyle = DropDownStyle.DropDownList,
Visible = false
};
ucmboComputeOperator.SetDataSource<CalculationType>();
Controls.Add(ucmboComputeOperator);
}
c[nameof(ApprovalExceptionRead.ComputeOperator)].EditorComponent = ucmboComputeOperator;

So, after all this, it does not work. We get an error when changing the value of the drop down in a row and calling grid.UpdateData

Object of type 'System.DBNull' cannot be converted to type 'CalculationType'

We think we understand why this is happening, so my questions are, in the context of using it with grid:

What is the standard way to set datasource of combo editor to enum?

What if we want to use description as display memeber?

Thanks,
M.