C# Datagridview:如何在编辑模式下设置单元格?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1814423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:03:51  来源:igfitidea点击:

Datagridview: How to set a cell in editing mode?

c#winforms.net-3.5datagridview

提问by josecortesp

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 case, it doesn't.

我需要以编程方式在编辑模式下设置一个单元格。我知道将该单元格设置为 CurrentCell 然后调用方法 BeginEdit(bool),它应该发生,但在我的情况下,它没有。

I really want that, with my DGV with several columns, the user can ONLY select and also edit the first two. The other columns are already read-only, but the user can select them, and that is what I don't want.

我真的很想要,我的 DGV 有几列,用户只能选择和编辑前两列。其他列已经是只读的,但用户可以选择它们,这是我不想要的。

So I was thinking, tell the user to TAB everytime it has finished writing on the cell, then select the second cell, then tab again and it select and begin edit the next row's first cell...

所以我在想,每次在单元格上写完后告诉用户 TAB,然后选择第二个单元格,然后再次 Tab 并选择并开始编辑下一行的第一个单元格......

How can I do this?

我怎样才能做到这一点?

采纳答案by David Hall

Setting the CurrentCelland then calling BeginEdit(true)works well for me.

设置CurrentCell然后调用BeginEdit(true)对我来说效果很好。

The following code shows an eventHandler for the KeyDownevent that sets a cell to be editable.

以下代码显示了KeyDown将单元格设置为可编辑的事件的 eventHandler 。

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)

我的示例仅实现了所需的按键覆盖之一,但理论上其他的应该相同。(我总是将 [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);               
        }
    }

If you haven't found it previously, the DataGridView FAQis 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.

如果您以前没有找到它,DataGridView FAQ是一个很好的资源,由 DataGridView 控件的程序经理编写,它涵盖了您可能想用该控件执行的大部分操作。

回答by josecortesp

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 ReadOnlyshould be editable. You can use the DataGridView CellEnterevent to determine what cell was enteredand 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.

好吧,我会检查您的任何列是否设置为ReadOnly. 我从来没有使用过BeginEdit,但也许有一些合法的用途。完成后dataGridView1.Columns[".."].ReadOnly = False;,不可ReadOnly编辑的字段应该是可编辑的。您可以使用 DataGridViewCellEnter事件来确定输入了哪个单元格,然后在将编辑从前两列传递到下一组列并关闭对最后两列的编辑后,打开对这些单元格的编辑。

回答by sree ranjith c.k

private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e)
{
  if (DgvRoomInformation.CurrentCell.ColumnIndex == 4)  //example-'Column index=4'
  {
    DgvRoomInformation.BeginEdit(true);   
  }
}

回答by HodlDwon

I know this question is pretty old, but figured I'd share some demo code this question helped me with.

我知道这个问题已经很老了,但我想我会分享一些这个问题对我有帮助的演示代码。

  • Create a Form with a Buttonand a DataGridView
  • Register a Clickevent for button1
  • Register a CellClickevent for DataGridView1
  • Set DataGridView1's property EditModeto EditProgrammatically
  • Paste the following code into Form1:
  • 用 aButton和 a创建一个表单DataGridView
  • Click为 button1注册一个事件
  • CellClick为 DataGridView1注册一个事件
  • 将 DataGridView1 的属性设置EditModeEditProgrammatically
  • 将以下代码粘贴到 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);
                }
            }
        }
    }
}

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.

请注意,列索引号可能会因多次按下按钮一而发生变化,因此我总是按名称而不是索引值来引用列。我需要将 David Hall 的答案合并到我已经有 ComboBoxes 的演示中,因此他的答案非常有效。

回答by gridtrak

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).

我知道这是一个老问题,但没有一个答案对我有用,因为我想在可能执行其他事件(如工具栏按钮单击、菜单选择等)时可靠地(始终能够)将单元格设置为编辑模式。这些事件返回后可能会影响默认焦点。我最终需要一个计时器并调用。以下代码位于派生自 DataGridView 的新组件中。这段代码让我可以myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName);随时调用,我想任意将数据绑定单元格设置为编辑模式(假设单元格不是只读模式)。

// 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;
    }
  }
}