I have a DataGridView with a few DataGridViewComboBoxColumns. There is a CellEnter event handler on the DataGridView for the purpose of single-click dropping down of the comboboxes.
The column is bound to a List of KeyValuePairs, ValueMember being “Key”, and DisplayMember being “Value”.
When I click on a combobox column, it works fine. However, if the cell is in the “dropdown” state and I click on another combobox (same column, different row), it properly deselects the old cell, selects and drops down the new cell, however the selected value on top changes to the value from the old cell for a split second, before changing back to the correct one.
For example, let’s say the list is A, B, C. In row1, A is selected, in row2, B is selected. I click the cell in row1, all is as it should be. Then, while this cell is dropped down, I click on the cell in row2. It drops down properly, but the selected value on top becomes A, then switches back to B (the correct one) immediately.
If I click on a cell in some other column before clicking the second combobox cell, this doesn’t happen.
Is there a way to prevent this from happening?
Example code to reproduce the problem (the event handlers are hooked up to the obvious events):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PDGV
{
public partial class Form1 : Form
{
List<KeyValuePair<string, string>> bindingList = new List<KeyValuePair<string, string>>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Rows.Add(10);
bindingList.Add(new KeyValuePair<string,string>("aaa", "111"));
bindingList.Add(new KeyValuePair<string,string>("bbb", "222"));
bindingList.Add(new KeyValuePair<string,string>("ccc", "333"));
bindingList.Add(new KeyValuePair<string,string>("ddd", "444"));
bindingList.Add(new KeyValuePair<string,string>("eee", "555"));
BindComboList(2, bindingList);
}
private void BindComboList(int columnIndex, object list)
{
var column = dataGridView1.Columns[columnIndex] as DataGridViewComboBoxColumn;
if (column != null)
{
column.DataSource = new BindingSource(list, null);
column.DisplayMember = "Value";
column.ValueMember = "Key";
}
}
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1)
return;
dataGridView1.BeginEdit(true);
var control = dataGridView1.EditingControl as DataGridViewComboBoxEditingControl;
if (control != null)
control.DroppedDown = true;
}
}
}
The Cuase:
Deep down in
DataGridView‘s EndEdit method it stores a copy of the previously used EditingControlthis.latestEditingControl = this.editingControl;Then when you start editing another cell it Kicks inBeginEditInternal. During this it checks if the latestEditingControl is not null and the editing types are the same as the last cell, if so it reuses the control, which is why you see the flash, it really is the same control.The Solution:
Set the latestEditingControl to null, this control is not accessible through normal properties/methods, have to use reflection. NOTE: This leads to a totally different annoyance, now the cell you are leaving flashes white :), but it does resolve the specific issue you asked for help on.