I need to programmatically set a cell in editing mode. I know that setting that cell as CurrentCell and then call the method BeginEdit(bool), it should happen, but in my cas
private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (DgvRoomInformation.CurrentCell.ColumnIndex == 4) //example-'Column index=4'
{
DgvRoomInformation.BeginEdit(true);
}
}
Well, I would check if any of your columns are set as ReadOnly
. I have never had to use BeginEdit, but maybe there is some legitimate use. Once you have done dataGridView1.Columns[".."].ReadOnly = False;
, the fields that are not ReadOnly
should be editable. You can use the DataGridView CellEnter
event to determine what cell was entered and then turn on editing on those cells after you have passed editing from the first two columns to the next set of columns and turn off editing on the last two columns.
I know this is an old question, but none of the answers worked for me, because I wanted to reliably (always be able to) set the cell into edit mode when possibly executing other events like Toolbar Button clicks, menu selections, etc. that may affect the default focus after those events return. I ended up needing a timer and invoke. The following code is in a new component derived from DataGridView. This code allows me to simply make a call to myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName);
anytime I want to arbitrarily set a databound cell to edit mode (assuming the cell is Not in ReadOnly mode).
// If the DGV does not have Focus prior to a toolbar button Click,
// then the toolbar button will have focus after its Click event handler returns.
// To reliably set focus to the DGV, we need to time it to happen After event handler procedure returns.
private string m_SelectCellFocus_DataPropertyName = "";
private System.Timers.Timer timer_CellFocus = null;
public void CurrentRow_SelectCellFocus(string sDataPropertyName)
{
// This procedure is called by a Toolbar Button's Click Event to select and set focus to a Cell in the DGV's Current Row.
m_SelectCellFocus_DataPropertyName = sDataPropertyName;
timer_CellFocus = new System.Timers.Timer(10);
timer_CellFocus.Elapsed += TimerElapsed_CurrentRowSelectCellFocus;
timer_CellFocus.Start();
}
void TimerElapsed_CurrentRowSelectCellFocus(object sender, System.Timers.ElapsedEventArgs e)
{
timer_CellFocus.Stop();
timer_CellFocus.Elapsed -= TimerElapsed_CurrentRowSelectCellFocus;
timer_CellFocus.Dispose();
// We have to Invoke the method to avoid raising a threading error
this.Invoke((MethodInvoker)delegate
{
Select_Cell(m_SelectCellFocus_DataPropertyName);
});
}
private void Select_Cell(string sDataPropertyName)
{
/// When the Edit Mode is Enabled, set the initial cell to the Description
foreach (DataGridViewCell dgvc in this.SelectedCells)
{
// Clear previously selected cells
dgvc.Selected = false;
}
foreach (DataGridViewCell dgvc in this.CurrentRow.Cells)
{
// Select the Cell by its DataPropertyName
if (dgvc.OwningColumn.DataPropertyName == sDataPropertyName)
{
this.CurrentCell = dgvc;
dgvc.Selected = true;
this.Focus();
return;
}
}
}
I know this question is pretty old, but figured I'd share some demo code this question helped me with.
Button
and a DataGridView
Click
event for button1CellClick
event for DataGridView1EditMode
to EditProgrammatically
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
DataTable m_dataTable;
DataTable table { get { return m_dataTable; } set { m_dataTable = value; } }
private const string m_nameCol = "Name";
private const string m_choiceCol = "Choice";
public Form1()
{
InitializeComponent();
}
class Options
{
public int m_Index { get; set; }
public string m_Text { get; set; }
}
private void button1_Click(object sender, EventArgs e)
{
table = new DataTable();
table.Columns.Add(m_nameCol);
table.Rows.Add(new object[] { "Foo" });
table.Rows.Add(new object[] { "Bob" });
table.Rows.Add(new object[] { "Timn" });
table.Rows.Add(new object[] { "Fred" });
dataGridView1.DataSource = table;
if (!dataGridView1.Columns.Contains(m_choiceCol))
{
DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn();
txtCol.Name = m_choiceCol;
dataGridView1.Columns.Add(txtCol);
}
List<Options> oList = new List<Options>();
oList.Add(new Options() { m_Index = 0, m_Text = "None" });
for (int i = 1; i < 10; i++)
{
oList.Add(new Options() { m_Index = i, m_Text = "Op" + i });
}
for (int i = 0; i < dataGridView1.Rows.Count - 1; i += 2)
{
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
//Setup A
c.DataSource = oList;
c.Value = oList[0].m_Text;
c.ValueMember = "m_Text";
c.DisplayMember = "m_Text";
c.ValueType = typeof(string);
////Setup B
//c.DataSource = oList;
//c.Value = 0;
//c.ValueMember = "m_Index";
//c.DisplayMember = "m_Text";
//c.ValueType = typeof(int);
//Result is the same A or B
dataGridView1[m_choiceCol, i] = c;
}
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns.IndexOf(dataGridView1.Columns[m_choiceCol]))
{
DataGridViewCell cell = dataGridView1[m_choiceCol, e.RowIndex];
dataGridView1.CurrentCell = cell;
dataGridView1.BeginEdit(true);
}
}
}
}
}
Note that the column index numbers can change from multiple button presses of button one, so I always refer to the columns by name not index value. I needed to incorporate David Hall's answer into my demo that already had ComboBoxes so his answer worked really well.
Setting the CurrentCell
and then calling BeginEdit(true)
works well for me.
The following code shows an eventHandler for the KeyDown
event that sets a cell to be editable.
My example only implements one of the required key press overrides but in theory the others should work the same. (and I'm always setting the [0][0] cell to be editable but any other cell should work)
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && dataGridView1.CurrentCell.ColumnIndex == 1)
{
e.Handled = true;
DataGridViewCell cell = dataGridView1.Rows[0].Cells[0];
dataGridView1.CurrentCell = cell;
dataGridView1.BeginEdit(true);
}
}
If you haven't found it previously, the DataGridView FAQ is a great resource, written by the program manager for the DataGridView control, which covers most of what you could want to do with the control.