.NET 4.x Отслеживание изменения DataGridViewComboBoxCell - C#
Формулировка задачи:
Добый день. Начал изучать С# и столкнулся с одной проблеймой.
Есть таблица DataViewGrid, в которую дабавляю данные из БД. В этой таблице мне нужно изменять данные. Для удобства я добавил 3 списка.
Вот код добавления:
Мне нужно отследить изменения в списке "cmb". Т.е. Если там выбрано "Машинист", то в списке "cmb1" нужно добавить список классов, если выбрано что-либо другое, то список очищаю.
Я думал, что в DataGridViewComboBoxCell есть события, а их увы нет... Сделал по событию "CellParsing".
Вот код события:
Но проблема в том, что при первом выборе элемента списка значение не заносится в cmb.Value. Нужно выбрать еще раз и тогда прошлой выбранное внесется в Value. Так же после выбора элемента нужно кликнуть на любой ячейке таблицы, что бы вызвать событие CellParsing.
Подскажите как правильно сделать отслеживание изменения значений в списке, что бы не счелкать на любой ячейке и не выбирать два раза значение... То что смог придумать это сделать свой класс DataGridViewComboBoxCell с добавлением события изменения значения ячейки, но для этого моих знаний пока не хватает...
Буду очнь благодарен за помощь
DataGridViewComboBoxCell cmb = new DataGridViewComboBoxCell();
DataGridViewComboBoxCell cmb1 = new DataGridViewComboBoxCell();
DataGridViewComboBoxCell cmb2 = new DataGridViewComboBoxCell();
cmb.MaxDropDownItems = 5;
cmb.Items.Add("Машинист");
cmb.Items.Add("Помощник");
cmb.Items.Add("Дублер");
cmb.Items.Add("Машинист - инструктор");
cmb.Items.Add("Водитель");
dataGridView1.Rows[6].Cells[0] = cmb;
cmb.Value = (string)dataReader["post"];
cmb2.MaxDropDownItems = 2;
cmb2.Items.Add("М");
cmb2.Items.Add("Ж");
dataGridView1.Rows[10].Cells[0] = cmb2;
cmb2.Value = (string)dataReader["gender"];
if (cmb.Value.ToString() == "Машинист")
{
cmb1.MaxDropDownItems = 3;
cmb1.Items.Add("1 кл");
cmb1.Items.Add("2 кл");
cmb1.Items.Add("3 кл");
dataGridView1.Rows[7].Cells[0] = cmb1;
cmb1.Value = (string)dataReader["class"];
}
else
{
cmb1.MaxDropDownItems = 1;
dataGridView1.Rows[7].Cells[0] = cmb1;
}private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
if (e.RowIndex == 6)
{
//MessageBox.Show(cmb.Selected.ToString());
if (cmb.Value.ToString() == "Машинист")
{
if (cmb1.MaxDropDownItems == 1)
{
cmb1.MaxDropDownItems = 3;
cmb1.Items.Add("1 кл");
cmb1.Items.Add("2 кл");
cmb1.Items.Add("3 кл");
}
}
else
{
cmb1.MaxDropDownItems = 1;
cmb1.Value = null;
cmb1.Items.Clear();
}
}
}
Вроде получилось, наверно, не совсем правильно... Но увы, пока так. Если можно по другому посоветуйте как.
//определение ячейки, на которую нажали. И в зависимости от выбранной ячейки выводятся разные списки
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
SetComboBoxCellType objChangeCellType = new SetComboBoxCellType(ChangeCellToComboBox);
if (e.RowIndex == 6)
{
this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
bIsComboBox = false;
}
if (e.RowIndex == 7)
{
this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
bIsComboBox = false;
}
if (e.RowIndex == 10)
{
this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
bIsComboBox = false;
}
}
//создание и вывод списков в зависимости от нажатой ячейки
private void ChangeCellToComboBox(int iRowIndex)
{
if (iRowIndex == 6)
{
if (bIsComboBox == false)
{
DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
DataTable dt = new DataTable();
dt.Columns.Add("work", typeof(string));
//for (int i = 0; i < 5; i++)
//{
//DataRow dr = dt.NewRow();
//dr["Name"] = "Name - " + i.ToString();
dt.Rows.Add("Машинист");
dt.Rows.Add("Помощник");
dt.Rows.Add("Машинист - инструктор");
dt.Rows.Add("Водитель");
dt.Rows.Add("Дублер");
//}
//for (int i = 0; i < 5; i++)
dgComboCell.DataSource = dt;
dgComboCell.ValueMember = "work";
dgComboCell.DisplayMember = "work";
try
{
MessageBox.Show(dgComboCell.Value.ToString());
}
catch
{ }
dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
bIsComboBox = true;
}
}
if (iRowIndex == 7)
{
if (bIsComboBox == false)
{
DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
DataTable dt = new DataTable();
dt.Columns.Add("class", typeof(string));
//for (int i = 0; i < 5; i++)
//{
//DataRow dr = dt.NewRow();
//dr["Name"] = "Name - " + i.ToString();
dt.Rows.Add("1 кл");
dt.Rows.Add("2 кл");
dt.Rows.Add("3 кл");
//}
//for (int i = 0; i < 5; i++)
dgComboCell.DataSource = dt;
dgComboCell.ValueMember = "class";
dgComboCell.DisplayMember = "class";
dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
bIsComboBox = true;
}
}
if (iRowIndex == 10)
{
if (bIsComboBox == false)
{
DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
DataTable dt = new DataTable();
dt.Columns.Add("gender", typeof(string));
//for (int i = 0; i < 5; i++)
//{
//DataRow dr = dt.NewRow();
//dr["Name"] = "Name - " + i.ToString();
dt.Rows.Add("М");
dt.Rows.Add("Ж");
//}
//for (int i = 0; i < 5; i++)
dgComboCell.DataSource = dt;
dgComboCell.ValueMember = "gender";
dgComboCell.DisplayMember = "gender";
dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
bIsComboBox = true;
}
}
}
//после завершения изменения обрабатываю событие и смотрю что было выбрано. Если выбрано "Машинист", то разрешаю изменение ячейки со списком класс, в противном случае запрещаю изменение ячейки.
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == 6)
{
if (dataGridView1[0, 6].Value != null)
{
if (dataGridView1[0, 6].Value.ToString() != "Машинист")
{
dataGridView1.Rows[7].Cells[0].ReadOnly = true;
}
else
{
dataGridView1.Rows[7].Cells[0].ReadOnly = false;
}
}
}
}Решение задачи: «.NET 4.x Отслеживание изменения DataGridViewComboBoxCell»
textual
Листинг программы
public delegate void valchng(object sender, EventArgs e);
public class MyDataGridViewComboBoxCell : DataGridViewComboBoxCell
{
public event valchng ValueChanged;
protected override bool SetValue(int rowIndex, object value)
{
if (ValueChanged != null && rowIndex!=-1)
{
base.SetValue(rowIndex, value);
ValueChanged(this, new EventArgs());
return true;
} return base.SetValue(rowIndex, value);
}
protected override object GetValue(int rowIndex)
{
return base.GetValue(rowIndex);
}
}