Datagridview: Как установить ячейку в режиме редактирования?
Мне нужно программно установить ячейку в режиме редактирования. Я знаю, что установка этой ячейки как CurrentCell, а затем вызов метода BeginEdit (bool), это должно произойти, но в моем случае это не так.
Я действительно хочу, чтобы с моим DGV с несколькими столбцами пользователь мог ТОЛЬКО выбирать, а также редактировать первые два. Другие столбцы уже доступны только для чтения, но пользователь может их выбрать, и это то, чего я не хочу.
Итак, я думал, сообщите пользователю TAB каждый раз, когда он закончил запись в ячейке, затем выберите вторую ячейку, затем снова вкладку и выберите и начните редактировать следующую ячейку первой строки...
Как я могу это сделать?
Ответы
Ответ 1
Настройка CurrentCell
, а затем вызов BeginEdit(true)
подходит для меня.
Следующий код показывает eventHandler для события KeyDown
, который задает ячейку для редактирования.
В моем примере реализовано только одно из обязательных ключевых прессов, но теоретически другие должны работать одинаково. (и я всегда устанавливаю ячейку [0] [0] для редактирования, но любая другая ячейка должна работать)
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);
}
}
Если вы не нашли его ранее, FAQ DataGridView - отличный ресурс, написанный менеджером программ для элемента управления DataGridView, который охватывает большую часть того, что вы могли бы хотеть сделать с помощью элемента управления.
Ответ 2
private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e)
{
if (DgvRoomInformation.CurrentCell.ColumnIndex == 4) //example-'Column index=4'
{
DgvRoomInformation.BeginEdit(true);
}
}
Ответ 3
Ну, я бы проверить, установлен ли какой-либо из ваших столбцов как ReadOnly
. Мне никогда не приходилось использовать BeginEdit, но, возможно, есть законное использование. После того, как вы сделали dataGridView1.Columns[".."].ReadOnly = False;
, поля, которые не являются ReadOnly
, должны быть доступны для редактирования. Вы можете использовать событие DataGridView CellEnter
, чтобы определить, какая ячейка была введена, а затем включить редактирование на этих ячейках после того, как вы прошли редактирование из первых двух столбцов в следующий набор столбцов и отключили редактирование в последних двух столбцах.
Ответ 4
Я знаю, что этот вопрос довольно старый, но решил, что я поделюсь некоторым демо-кодом, который мне помог.
- Создайте форму с
Button
и DataGridView
- Зарегистрируйте событие
Click
для кнопки 1
- Зарегистрируйте событие
CellClick
для DataGridView1
- Установить свойство DataGridView1
EditMode
в EditProgrammatically
- Вставьте следующий код в Form1:
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);
}
}
}
}
}
Обратите внимание, что номера индексов столбцов могут меняться от нескольких нажатий кнопок кнопки один, поэтому я всегда ссылаюсь на столбцы по имени, а не по индексу. Мне нужно было включить ответ Дэвида Холла в мою демоверсию, у которой уже были ComboBoxes, поэтому его ответ сработал очень хорошо.
Ответ 5
Я знаю, что это старый вопрос, но ни один из ответов не работал у меня, потому что я хотел надежно (всегда быть в состоянии) установить ячейку в режим редактирования, когда возможно выполнение других событий, таких как щелчки кнопки панели инструментов, выбор меню, и т.д., которые могут повлиять на фокус по умолчанию после возвращения этих событий. Я закончил тем, что мне нужен таймер и вызывается. Следующий код находится в новом компоненте, полученном из DataGridView. Этот код позволяет мне просто сделать вызов myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName);
в любое время, когда я хочу произвольно установить ячейку привязки данных в режим редактирования (предполагая, что ячейка не находится в режиме ReadOnly).
// 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 Click Event to select and set focus to a Cell in the DGV 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;
}
}
}