web-dev-qa-db-ja.com

Datagridview:編集モードでセルを設定する方法は?

編集モードでセルをプログラムで設定する必要があります。そのセルをCurrentCellとして設定してからBeginEdit(bool)メソッドを呼び出すと、それが起こるはずですが、私の場合はそうではありません。

DGVに複数の列がある場合、ユーザーは最初の2つだけを選択して編集することができます。他の列は既に読み取り専用ですが、ユーザーはそれらを選択できますが、それは私が望んでいないことです。

だから私は考えていました、セルへの書き込みが終了するたびにユーザーにTABを押してから、2番目のセルを選択してからもう一度タブを押して、次の行の最初のセルを選択して編集を開始します...

これどうやってするの?

28
josecortesp

CurrentCellを設定してからBeginEdit(true)を呼び出すとうまくいきます。

次のコードは、セルを編集可能に設定するKeyDownイベントのeventHandlerを示しています。

私の例では、必要なキープレスオーバーライドの1つのみを実装していますが、理論的には他のキープレスオーバーライドも同じように動作するはずです。 (そして、[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);               
        }
    }

以前に見つからなかった場合、 DataGridView FAQ は、DataGridViewコントロールのプログラムマネージャーによって書かれた素晴らしいリソースであり、コントロールで実行できることのほとんどをカバーしています。

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

さて、列のいずれかがReadOnlyとして設定されているかどうかを確認します。 BeginEditを使用する必要はありませんでしたが、正当な使用法があるかもしれません。完了したらdataGridView1.Columns[".."].ReadOnly = False;ReadOnly以外のフィールドは編集可能である必要があります。 DataGridView CellEnterイベントを使用して、どのセルが入力であったかを判別し、最初の2列から次の列セットに編集を渡した後、それらのセルの編集をオンにし、最後の2列の編集をオフにします。

3
user195488

私はこの質問がかなり古いことを知っていますが、この質問が私を助けたいくつかのデモコードを共有すると思いました。

  • ButtonDataGridViewを含むフォームを作成します
  • Button1のClickイベントを登録します
  • DataGridView1のCellClickイベントを登録します
  • 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);
                }
            }
        }
    }
}

列のインデックス番号は、ボタン1の複数のボタンを押すと変更される可能性があるため、インデックス値ではなく名前で列を常に参照することに注意してください。すでにComboBoxが含まれているデモにDavid Hallの回答を組み込む必要があったため、彼の回答は非常にうまく機能しました。

1
HodlDwon

私はこれが古い質問であることを知っていますが、ツールバーボタンのクリック、メニューの選択などの他のイベントを実行する可能性があるときにセルを確実に(常に)編集モードに設定したいので、答えは私にはうまくいきませんでしたこれらのイベントが戻った後、デフォルトのフォーカスに影響する場合があります。私はタイマーと呼び出しを必要とすることになりました。次のコードは、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'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;
    }
  }
}
0
gridtrak