Народ, 2 сутки ломаю голову...........
Как в DataGridViewComboBoxColumn запихнуть null, если колонка таблицы типа integer?
именно типа integer, а не string. потому что если string я могу это сделать.
специально для сего вопроса набросал пример:
там DataGridView с 4 колонками, 2 из которых отображают данные из одной колонки таблицы ( Type )
причем одна типа DataGridViewTextBoxColumn, а другая DataGridViewComboBoxColumn.
так вот в текстовое поле я могу вставить NULL, (скорее DBNull.Value) просто написав <NULL> либо нажав <Ctrl>+<0>.
а в комбобоксе при выборе -неизвестно- вставляется не null a -1, а при нажатии <Ctrl>+<0>, вообше вылетает ошибка System.FormatException.
вот пример:
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace GridComboForForum
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MyTestForm());
}
}
class MyTestForm : Form
{
DataTable _table;
DataGridView _grid;
public MyTestForm()
{
this.Load += new EventHandler(frmExp_Load);
}
void frmExp_Load(object sender, EventArgs e)
{
this.Text = "Test form";
this.Width = 640;
this.Height = 300;
this.CreateTable();
this.FillData();
this.CreateGrid();
}
private void CreateGrid()
{
// сам грид
this._grid = new DataGridView();
this._grid.Width = 610;
this._grid.Height = 250;
this._grid.Location = new System.Drawing.Point(10, 10);
this._grid.AutoGenerateColumns = false;
this._grid.AllowUserToAddRows = false;
// колонки
// ID
DataGridViewTextBoxColumn colID = new DataGridViewTextBoxColumn();
colID.DataPropertyName = "ID";
colID.HeaderText = "ID";
colID.Width = 50;
this._grid.Columns.Add(colID);
// Type: вот тут я сделал 2 колонки грида связанные с одной колонкой таблицы : type
// первая колонка - текстовая, тут все понятно и все работает.
DataGridViewTextBoxColumn colTypeTxt = new DataGridViewTextBoxColumn();
colTypeTxt.DataPropertyName = "Type";
colTypeTxt.HeaderText = "Type (textbox)";
colTypeTxt.DefaultCellStyle.NullValue = "<NULL>";
colTypeTxt.ValueType = typeof(int);
this._grid.Columns.Add(colTypeTxt);
// а вот здесь "камень преткновения" комбобокс!!!
DataGridViewComboBoxColumn colTypeCombo = new DataGridViewComboBoxColumn();
colTypeCombo.DataPropertyName = "Type";
colTypeCombo.HeaderText = "Type (combobox)";
colTypeCombo.Width = 150;
colTypeCombo.DefaultCellStyle.NullValue = "-1";
colTypeCombo.Items.Add(new TypeItem(-1, "-неизвестно-"));
colTypeCombo.Items.Add(new TypeItem(1, "блондин"));
colTypeCombo.Items.Add(new TypeItem(2, "брюнет"));
colTypeCombo.Items.Add(new TypeItem(3, "шатен"));
colTypeCombo.DisplayMember = "Name";
colTypeCombo.ValueMember = "ID";
this._grid.Columns.Add(colTypeCombo);
// Name column
DataGridViewTextBoxColumn colName = new DataGridViewTextBoxColumn();
colName.DataPropertyName = "Name";
colName.HeaderText = "Name";
colName.Width = 150;
this._grid.Columns.Add(colName);
// set data source
this._grid.DataSource = this._table;
this.Controls.Add(this._grid);
}
// добавляем 3 человека
private void FillData()
{
DataRow row;
row = this._table.NewRow();
row["Type"] = 2;
row["Name"] = "Вася";
this._table.Rows.Add(row);
row = this._table.NewRow();
// в данном случае тип волос неизвестен
// row["Type"] = 1;
row["Name"] = "Петя";
this._table.Rows.Add(row);
row = this._table.NewRow();
row["Type"] = 1;
row["Name"] = "Коля";
this._table.Rows.Add(row);
}
private void CreateTable()
{
this._table = new DataTable();
// первичный ключ
DataColumn colId = new DataColumn("ID", typeof(int));
colId.AutoIncrement = true;
colId.AutoIncrementSeed = 1;
// какой-то классификатор ( к примеру тип волос )
DataColumn colType = new DataColumn("Type", typeof(int));
colType.AllowDBNull = true;
// имя человека
DataColumn colName = new DataColumn("Name", typeof(string));
_table.Columns.Add(colId);
_table.Columns.Add(colType);
_table.Columns.Add(colName);
DataColumn[] keys = new DataColumn[1];
keys[0] = colId;
_table.PrimaryKey = keys;
}
}
// класс для хранения типов чего-либо ( в данном случае типов волос )
public class TypeItem
{
private int _id;
private string _name;
public TypeItem(int id, string name)
{
this.ID = id;
this.Name = name;
}
public int ID
{
get { return this._id; }
set { this._id = value; }
}
public string Name
{
get { return this._name; }
set { this._name = value; }
}
public override string ToString()
{
return this.ID.ToString() + " - " + this.Name;
}
}
}
Заранее благодарен.
Решение нашел!
Пример:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
namespace MSComboSample
{
public class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new frmTest());
}
}
public class frmTest : Form
{
DataGridView _grdTask = new DataGridView();
DataSet _dataSet;
public frmTest()
{
this.Load += new EventHandler(frmTest_Load);
}
void frmTest_Load(object sender, EventArgs e)
{
this.Text = "DataGridViewComboBoxColumn test form";
this.Width = 530;
this.Height = 260;
this.CreateDataSet();
this.FillData();
this.CreateGrids();
}
private void CreateGrids()
{
// size, location
this._grdTask.Size = new Size(500, 210);
this._grdTask.Location = new Point(10, 10);
// columns
this._grdTask.AutoGenerateColumns = false;
DataGridViewTextBoxColumn colID = new DataGridViewTextBoxColumn();
colID.HeaderText = "ID";
colID.DataPropertyName = "ID";
colID.ReadOnly = true;
DataGridViewComboBoxColumn colEmpID = new DataGridViewComboBoxColumn();
colEmpID.Name = "EmpID";
colEmpID.HeaderText = "Employee ID";
colEmpID.DataPropertyName = "EmployeeID";
colEmpID.DisplayMember = "Name";
colEmpID.ValueMember = "ID";
// populate items
// null value
colEmpID.Items.Add(new ComboItem(DBNull.Value, "not assigned"));
// employees
foreach (DataRow row in this._dataSet.Tables["Employee"].Rows)
colEmpID.Items.Add(new ComboItem(row["ID"], row["Name"].ToString()));
// check column
DataGridViewTextBoxColumn colCheck = new DataGridViewTextBoxColumn();
colCheck.HeaderText = "Check EmpID value";
colCheck.DataPropertyName = "EmployeeID";
colCheck.Width = 130;
colCheck.DefaultCellStyle.NullValue = "<NULL>";
DataGridViewTextBoxColumn colTask = new DataGridViewTextBoxColumn();
colTask.HeaderText = "Task";
colTask.DataPropertyName = "Task";
this._grdTask.Columns.Add(colID);
this._grdTask.Columns.Add(colEmpID);
this._grdTask.Columns.Add(colCheck);
this._grdTask.Columns.Add(colTask);
// data source
this._grdTask.DataSource = this._dataSet;
this._grdTask.DataMember = "Task";
this.Controls.Add(this._grdTask);
// for <Ctrl>+<0>
this._grdTask.KeyDown += new KeyEventHandler(_grdTask_KeyDown);
}
// <Ctrl>+<0>
void _grdTask_KeyDown(object sender, KeyEventArgs e)
{
if (this._grdTask.CurrentCell.ColumnIndex == this._grdTask.Columns["EmpID"].Index)
{
if (e.Control && (e.KeyCode == Keys.D0 || e.KeyCode == Keys.NumPad0))
{
this._grdTask.CurrentCell.Value = DBNull.Value;
e.Handled = true;
}
}
}
private void FillData()
{
DataRow row;
// employee
row = this._dataSet.Tables["Employee"].NewRow();
row["Name"] = "Emp 1";
this._dataSet.Tables["Employee"].Rows.Add(row);
row = this._dataSet.Tables["Employee"].NewRow();
row["Name"] = "Emp 2";
this._dataSet.Tables["Employee"].Rows.Add(row);
row = this._dataSet.Tables["Employee"].NewRow();
row["Name"] = "Emp 3";
this._dataSet.Tables["Employee"].Rows.Add(row);
// task
row = this._dataSet.Tables["Task"].NewRow();
row["Task"] = "Task 1";
this._dataSet.Tables["Task"].Rows.Add(row);
row = this._dataSet.Tables["Task"].NewRow();
row["EmployeeID"] = 3;
row["Task"] = "Task 2";
this._dataSet.Tables["Task"].Rows.Add(row);
row = this._dataSet.Tables["Task"].NewRow();
row["Task"] = "Task 3";
this._dataSet.Tables["Task"].Rows.Add(row);
}
private void CreateDataSet()
{
this._dataSet = new DataSet();
// employees
DataTable tEmployee = new DataTable("Employee");
// id
DataColumn colEmpID = new DataColumn("ID", typeof(int));
colEmpID.AutoIncrement = true;
colEmpID.AutoIncrementSeed = 1;
colEmpID.Unique = true;
colEmpID.AllowDBNull = false;
// name
DataColumn colEmpName = new DataColumn("Name", typeof(string));
tEmployee.Columns.Add(colEmpID);
tEmployee.Columns.Add(colEmpName);
tEmployee.PrimaryKey = new DataColumn[] { colEmpID };
// tasks
DataTable tTask = new DataTable("Task");
// id
DataColumn colTaskID = new DataColumn("ID", typeof(int));
colTaskID.AutoIncrement = true;
colTaskID.AutoIncrementSeed = 1;
colTaskID.Unique = true;
colTaskID.AllowDBNull = false;
// employee id
DataColumn colTaskEmpID = new DataColumn("EmployeeID", typeof(int));
colTaskEmpID.AllowDBNull = true;
colTaskEmpID.DefaultValue = DBNull.Value;
// task name
DataColumn colTaskName = new DataColumn("Task", typeof(string));
tTask.Columns.Add(colTaskID);
tTask.Columns.Add(colTaskEmpID);
tTask.Columns.Add(colTaskName);
tTask.PrimaryKey = new DataColumn[] { colTaskID };
this._dataSet.Tables.Add(tEmployee);
this._dataSet.Tables.Add(tTask);
DataRelation rel = new DataRelation("TaskEmployee", colEmpID, colTaskEmpID);
}
}
public class ComboItem
{
private object _id;
private string _name;
public ComboItem(object id, string name)
{
this._id = id;
this._name = name;
}
public object ID
{
get { return this._id; }
set { this._id = value; }
}
public string Name
{
get { return this._name; }
set { this._name = value; }
}
}
}