1

I have a datagridview with a combobox column that is bound to an enum as follows:

     var D = (DataGridViewComboBoxColumn)dgvInputs.Columns[2];
     D.ValueType = typeof(MyType);
     D.ValueMember = "Value";
     D.DisplayMember = "Display";
     D.DataSource = new MyType[] {
        MyType.Rev,
        MyType.Model,
        MyType.User,
        MyType.Status
     }.Select(x => new { Display = x.ToString(), Value = (int)x }).ToList();

The datagridview is then bound to a DataTable named ParameterTable:

     BindingSource ParamSource = new BindingSource();
     ParamSource.DataSource = DataEntry.ParameterTable;
     dgvInputs.AutoGenerateColumns = false;
     dgvInputs.DataSource = ParamSource;
     dgvInputs.Columns[0].DataPropertyName = "Name";
     dgvInputs.Columns[1].DataPropertyName = "Prompt";
     dgvInputs.Columns[2].DataPropertyName = "Type";
     dgvInputs.Columns[3].DataPropertyName = "Width";
     dgvInputs.Columns[4].DataPropertyName = "Default Value";

When the user finishes editing the table, I need to validate it. In particular, I need to test that the Type has been defined in each row, and that the Default Value is compatible with the Type.

The problem is, every test I've found for checking if the Type has been set has failed. When I later try to cast the value as MyType as part of testing the default value, I get an error. When I check the .Value property on the empty Type cell in the debugger, it shows a value of "{}".

Currently, I have this code for the test, in the Validating event for the datagridview itself. I have tried various other versions and they have also failed:

     foreach (DataGridViewRow Row in dgvInputs.Rows) {
        if (!Row.IsNewRow) {
           // test other columns ...

           DataGridViewComboBoxCell Cell = (DataGridViewComboBoxCell)(Row.Cells[2]);
           if (Cell == null || Cell.Value as string == string.Empty) { 
               // Error ...
           }
           MyType PType = (MyType)(Cell.Value);

How can I test if a DataGridViewComboBox cell has not been set, and what is this value "{}"?

FYI - I am using VS 2008, and .Net 3.5 SP1. Not my choice. Just what is available to me.

Paul Sinclair
  • 223
  • 1
  • 12
  • What is the type of `DataEntry.ParameterTable`? – Ivan Stoev Dec 02 '15 at 20:12
  • Sorry. It's a DataTable – Paul Sinclair Dec 02 '15 at 20:17
  • if (Cell.Value == null) should tell when the cell is not set – Sergii Zhevzhyk Dec 02 '15 at 20:36
  • Assuming you fill the data source with ALL of the enum values, you can shorten it to `D.DataSource = Enum.GetValues(typeof(MyType));`. I'm quite sure that by default what will happen is the Display would be the `.ToString()` and the Value obviously be the enum value – Giora Guttsait Dec 02 '15 at 20:36
  • @GioraGuttsait - I don't. There are a couple of types for internal use only. But I'll keep that in mind if I decide to change that later. Thanks. – Paul Sinclair Dec 02 '15 at 20:40
  • @SergiiZhevzhyk - maybe it should. But it doesn't. That one I had tried before, and just checked again. Even though I never even entered the Type cell, it assigns it a value, which the debugger shows as "{}", not null. – Paul Sinclair Dec 02 '15 at 20:43
  • I looks like you are setting the datasource with an anonymous type, but for ValueType you are giving it your enum type. Why not just give it your enum directley – BenCamps Dec 02 '15 at 20:54
  • @bit2know - because if I did that, I would get the names as values, and then would have to add additional code to back the names out to the types. – Paul Sinclair Dec 02 '15 at 21:00

1 Answers1

1

There are a couple problems with this code.

First, D.ValueType = typeof(MyType); is incorrect because from what I see, you are binding to int field. Just remove that line, ValueType will be inferred from the data source.

Now, the main issue. When binding to a data table, the non entered value is represented by DBNull.Value. I would suggest you checking for both null and DBNull.Value. When entered, the value type in your case will be int, but you can safely unbox it to MyType.

The code should be something like this

//...
var value = Row.Cells[2].Value;
if (value == null || value == DBNull.Value)
{ 
    // Error ...
}
else
{
    var type = (MyType)value;
    // Check if type contains a valid value ...
}
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • That was what I needed. Thanks. The `D.ValueType = typeof` syntax I had picked up from another question somewhere on how to tie a comboboxcolumn to an enum. I'm still trying to figure out how datagridviews work. – Paul Sinclair Dec 02 '15 at 20:58