Make a Datagridview move to the next cell on Enter
To make a datagridview move to the next column when you press the enter you need to create a new control which inherits from datagridview. In the new control override PreProcessMessage to prevent the default enter key behavior. I also created a new column which converts an enter press to a tab key. Here is a simple c# example. A VB 2005 example is available on the VB-Tips website.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace EnterNextCell
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DGV dg = new DGV();
private void Form1_Load(object sender, EventArgs e)
{
dg.Dock = DockStyle.Fill;
this.Controls.Add(dg);
String strConn = "Server = .;Database = NorthWind;Integrated Security = SSPI;";
SqlConnection conn = new SqlConnection(strConn);
SqlDataAdapter da = new SqlDataAdapter("Select LastName, Notes from Employees", conn);
DataTable dt = new DataTable();
da.Fill(dt);
dg.DataSource = dt;
dg.Columns.Remove("LastName");
dg.Columns.Remove("Notes");
NoEnterColumn colName = new NoEnterColumn();
colName.DataPropertyName = "LastName";
NoEnterColumn colNotes = new NoEnterColumn();
colNotes.DataPropertyName = "Notes";
dg.Columns.Add(colName);
dg.Columns.Add(colNotes);
}
}
}
public class DGV : DataGridView
{
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int WM_CHAR = 0x0102;
public override bool PreProcessMessage(ref Message msg)
{
Keys keyCode = (Keys)(int)msg.WParam & Keys.KeyCode;
// for a datagrid, we need to eat the tab key oe else its done twice
if((msg.Msg == WM_KEYDOWN)
&& keyCode == Keys.Enter)
{
int intRow = this.CurrentCell.RowIndex;
int intCol = this.CurrentCell.ColumnIndex;
intCol++;
if(intCol==this.Columns.Count)
{
intCol=0;
intRow++;
if(intRow==this.Rows.Count)
{
intRow=0;
}
}
this.CurrentCell = this[intCol, intRow];
return true;
}
return base.PreProcessMessage(ref msg);
}
}
public class NoEnterColumn : DataGridViewColumn
{
public NoEnterColumn()
:
base(new NoEnterCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a CalendarCell.
if ((!(value == null)
&& !value.GetType().IsAssignableFrom(typeof(NoEnterCell))))
{
throw new InvalidCastException("Must be a NoEnterCell");
}
base.CellTemplate = value;
}
}
}
public class NoEnterCell : DataGridViewTextBoxCell
{
public NoEnterCell()
{
// Use the short date format.
}
public override Type EditType
{
get
{
// Return the type of the editing contol that CalendarCell uses.
return typeof(NoEnterEditingControl);
}
}
public override Type ValueType
{
get
{
// Return the type of the value that CalendarCell contains.
return typeof(string);
}
}
public override object DefaultNewRowValue
{
get
{
// Use the current date and time as the default value.
return "";
}
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
NoEnterEditingControl ctl = ((NoEnterEditingControl)(DataGridView.EditingControl));
ctl.Text = this.Value.ToString();
}
}
class NoEnterEditingControl : NoEnterTB, IDataGridViewEditingControl
{
private DataGridView dataGridViewControl;
private bool valueIsChanged = false;
private int rowIndexNum;
public NoEnterEditingControl()
{
}
public object EditingControlFormattedValue
{
get
{
return this.Text;
}
set
{
this.Text = value.ToString();
}
}
public int EditingControlRowIndex
{
get
{
return rowIndexNum;
}
set
{
rowIndexNum = value;
}
}
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}
public DataGridView EditingControlDataGridView
{
get
{
return dataGridViewControl;
}
set
{
dataGridViewControl = value;
}
}
// Implements the IDataGridViewEditingControl
// .EditingPanelCursor property.
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}
public bool EditingControlValueChanged
{
get
{
return valueIsChanged;
}
set
{
valueIsChanged = value;
}
}
public Cursor EditingControlCursor
{
get
{
return base.Cursor;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this.Text;
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
this.ForeColor = dataGridViewCellStyle.ForeColor;
this.BackColor = dataGridViewCellStyle.BackColor;
}
public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
{
// Let the DateTimePicker handle the keys listed.
return true;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
// No preparation needs to be done.
}
protected override void OnTextChanged(System.EventArgs e)
{
// Notify the DataGridView that the contents of the cell have changed.
valueIsChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
}
public class NoEnterTB : TextBox
{
private const int WM_KEYDOWN = 256;
private const int WM_KEYUP = 257;
private const int WM_CHAR = 258;
public override bool PreProcessMessage(ref System.Windows.Forms.Message msg)
{
Keys keyCode = (((Keys)(msg.WParam.ToInt32())) & Keys.KeyCode);
if (((msg.Msg == WM_KEYDOWN)
&& (keyCode == Keys.Enter)))
{
msg.WParam = new IntPtr((int)Keys.Tab);
}
return base.PreProcessMessage(ref msg);
}
}