public delegate void ComboValueChanged( int changingRow, object newValue ); // Step 1. Derive a custom column style from DataGridTextBoxColumn // a) add a ComboBox member // b) track when the combobox has focus in Enter and Leave events // c) override Edit to allow the ComboBox to replace the TextBox // d) override Commit to save the changed data public class DataGridComboBoxColumn : DataGridTextBoxColumn { public NoKeyUpCombo ColumnComboBox = null; private System.Windows.Forms.CurrencyManager _source = null; private int _rowNum; private bool _isEditing = false; ComboValueChanged _valueChanging;
public DataGridComboBoxColumn(ComboValueChanged valueChanging) : base() { _valueChanging = valueChanging; ColumnComboBox = new NoKeyUpCombo();
ColumnComboBox.Leave += new EventHandler(LeaveComboBox); // ColumnComboBox.Enter += new EventHandler(ComboMadeCurrent); ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged); ColumnComboBox.SelectionChangeCommitted += new System.EventHandler(ComboStartEditing);
// Step 1. Derive a custom column style from DataGridTextBoxColumn
// a) add a ComboBox member
// b) track when the combobox has focus in Enter and Leave events
// c) override Edit to allow the ComboBox to replace the TextBox
// d) override Commit to save the changed data
public class DataGridComboBoxColumn : DataGridTextBoxColumn
{
public NoKeyUpCombo ColumnComboBox = null;
private System.Windows.Forms.CurrencyManager _source = null;
private int _rowNum;
private bool _isEditing = false;
ComboValueChanged _valueChanging;
public DataGridComboBoxColumn(ComboValueChanged valueChanging) : base()
{
_valueChanging = valueChanging;
ColumnComboBox = new NoKeyUpCombo();
ColumnComboBox.Leave += new EventHandler(LeaveComboBox);
// ColumnComboBox.Enter += new EventHandler(ComboMadeCurrent);
ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged);
ColumnComboBox.SelectionChangeCommitted += new System.EventHandler(ComboStartEditing);
}
private void ComboStartEditing(object sender, EventArgs e)
{
_isEditing = true;
base.ColumnStartedEditing((Control) sender);
}
private void ComboIndexChanged(object sender, EventArgs e)
{
_valueChanging(_rowNum , ColumnComboBox.Text);
}// private void ComboMadeCurrent(object sender, EventArgs e)
// {
// //_isEditing = true;
// }
private void LeaveComboBox(object sender, EventArgs e)
{
if(_isEditing)
{
SetColumnValueAtRow(_source, _rowNum, ColumnComboBox.Text);
_isEditing = false;
Invalidate();
}
ColumnComboBox.Hide();
} protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
base.Edit(source,rowNum, bounds, readOnly, instantText , cellIsVisible); _rowNum = rowNum;
_source = source;
ColumnComboBox.Parent = this.TextBox.Parent;
ColumnComboBox.Location = this.TextBox.Location;
ColumnComboBox.Size = new Size(this.TextBox.Size.Width, ColumnComboBox.Size.Height);
ColumnComboBox.SelectedIndexChanged -= new System.EventHandler(ComboIndexChanged);
ColumnComboBox.Text = this.TextBox.Text;
ColumnComboBox.SelectedIndexChanged += new System.EventHandler(ComboIndexChanged); this.TextBox.Visible = false;
ColumnComboBox.Visible = true;
ColumnComboBox.BringToFront();
ColumnComboBox.Focus();
} protected override bool Commit(System.Windows.Forms.CurrencyManager dataSource, int rowNum)
{
if(_isEditing)
{
_isEditing = false;
SetColumnValueAtRow(dataSource, rowNum, ColumnComboBox.Text);
}
return true;
}
} public class NoKeyUpCombo : ComboBox
{
const int WM_KEYUP = 0x101;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if(m.Msg == WM_KEYUP)
{
//ignore keyup to avoid problem with tabbing & dropdownlist;
return;
}
base.WndProc(ref m);
}
}