How to create a list for a ComboBox that allows DBNull?
I tried int? But int? is not the same as DBNull and the combobox does not work with the null value.
My datagridview combobox, needs DBNull.
I did:
var machineComboList = this.eMDataSet1.Machines.Select(row => new
{
Key = (int?) row.MachineID,
Value = row.Description
}).ToList();
int? nullValue = DBNull.Value;
machineComboList.Add(new { Key = nullValue, Value = "All" });
I want to put a DBNull value into "Key". Using int? does not work.
Related: c# combobox binding and first null value
DBNull
is only intended for ADO.NET, to make a distinction between a missing value and a null value.
int?
can be null
-- this is probably what you're looking for. It can never be DBNull
, as they are incompatible types.
It is rare to work directly with DBNull
outside of ADO.NET calls. When reading from the database, you'll usually translate it like this:
object dbValue = ...;
int? intValue = dbValue != DBNull.Value ? (int)dbValue : (int?)null;
Or if you're a little more trusting of the data types returned, you can shorten it to this:
object dbValue = ...;
int? intValue = dbValue as int?;
This worked ... am sure there is a cleaner way
DataTable machineComboList = new DataTable();
machineComboList.Columns.Add("Value", typeof(string));
DataColumn machineIdColumn = machineComboList.Columns.Add("Key", typeof(int));
machineIdColumn.AllowDBNull = true;
foreach (EMDataSet1.MachinesRow machineRow in this.eMDataSet1.Machines)
{
DataRow comboBoxDataRow = machineComboList.NewRow();
comboBoxDataRow["Value"] = machineRow.Description;
comboBoxDataRow["Key"] = machineRow.MachineID;
machineComboList.Rows.Add(comboBoxDataRow);
}
DataRow nullComboBoxDataRow = machineComboList.NewRow();
nullComboBoxDataRow["Value"] = "All";
nullComboBoxDataRow["Key"] = DBNull.Value;
machineComboList.Rows.Add(nullComboBoxDataRow);
dataGridViewComboMachineID.DataSource = machineComboList;
dataGridViewComboMachineID.DisplayMember = "Value";
dataGridViewComboMachineID.ValueMember = "Key";
DBNull.Value
is not a type of integer, and it isn't actually null
itself either. Instead, it is a private class which represent a null value.
You can clearly see this in the reference source. It is a public sealed class with a private constructor and a singleton (static readonly) value to it.
Typically, when you have an int?
, or really, any null value, ADO.NET expects an actual value to be passed in. This is why you always see code that maps null
to DBNull.Value
:
using (var conn = ...)
using (var cmd = ...)
{
cmd.Parameters.AddWithValue("@MachineId", machineId == null ? DBNull.Value : machinId);
// ...
}
Now, on the flip side, how you want to represent null
in your user interface depends on you. Thought, it doesn't really make sense to represent it with DBNull.Value
, as that heavily ties your application to ADO.NET. What would happen if tomorrow you change to a different data store that wasn't sql?