webentwicklung-frage-antwort-db.com.de

Datagridview: Wie setzt man eine Zelle in den Bearbeitungsmodus?

Ich muss eine Zelle programmgesteuert in den Bearbeitungsmodus setzen. Ich kenne diese Zelle als CurrentCell und rufe dann die Methode BeginEdit (bool) auf. Das sollte passieren, aber in meinem Fall nicht.

Ich möchte wirklich, dass der Benutzer bei meinem DGV mit mehreren Spalten NUR die ersten beiden auswählen und auch bearbeiten kann. Die anderen Spalten sind bereits schreibgeschützt, aber der Benutzer kann sie auswählen, und das möchte ich nicht.

Also überlegte ich mir, ich sage dem Benutzer jedes Mal, wenn er die Zelle fertig geschrieben hat, TAB. Dann wählen Sie die zweite Zelle aus, klicken Sie dann erneut auf die Registerkarte, und wählen Sie aus, und beginnen Sie mit der Bearbeitung der ersten Zelle der nächsten Zeile.

Wie kann ich das machen?

28
josecortesp

Das Festlegen von CurrentCell und das anschließende Aufrufen von BeginEdit(true) funktioniert für mich gut.

Der folgende Code zeigt einen eventHandler für das Ereignis KeyDown, mit dem eine Zelle als bearbeitbar festgelegt wird. 

In meinem Beispiel wird nur eine der erforderlichen Tastendrucküberschreibungen implementiert, theoretisch sollten die anderen jedoch genauso funktionieren. (und ich setze die Zelle [0] [0] immer als bearbeitbar ein, aber jede andere Zelle sollte funktionieren)

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

Wenn Sie es noch nicht gefunden haben, ist DataGridView FAQ eine großartige Ressource, die vom Programmmanager für das DataGridView-Steuerelement geschrieben wurde. Dies deckt den größten Teil der möglichen Aufgaben des Steuerelements ab.

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

Nun, ich würde prüfen, ob eine Ihrer Spalten als ReadOnly gesetzt ist. Ich habe BeginEdit nie verwenden müssen, aber vielleicht gibt es eine legitime Verwendung. Sobald Sie dataGridView1.Columns[".."].ReadOnly = False; ausgeführt haben, sollten die Felder, die nicht ReadOnly sind, bearbeitet werden können. Sie können das DataGridView-Ereignis CellEnter verwenden, um festzustellen, welche Zelle eingegeben wurde und dann die Bearbeitung dieser Zellen aktivieren, nachdem Sie die Bearbeitung von den ersten beiden Spalten an die nächste Spaltengruppe übergeben und die Bearbeitung der letzten beiden Spalten deaktiviert haben .

2
user195488

Ich weiß, dass diese Frage ziemlich alt ist, aber ich dachte, ich würde einen Demo-Code teilen, mit dem diese Frage mir geholfen hat.

  • Erstellen Sie ein Formular mit einer Button und einer DataGridView
  • Registrieren Sie ein Click-Ereignis für button1
  • Registrieren Sie ein CellClick-Ereignis für DataGridView1
  • Legen Sie die Eigenschaft EditMode von DataGridView1 auf EditProgrammatically fest.
  • Fügen Sie den folgenden Code in Form1 ein:
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);
                }
            }
        }
    }
}

Beachten Sie, dass sich die Spaltenindexnummern von mehreren Tastendrücken der ersten Taste ändern können. Daher beziehe ich mich immer auf die Spalten nach Name und nicht auf den Indexwert. Ich musste die Antwort von David Hall in meine Demo integrieren, die bereits ComboBoxen hatte, und seine Antwort funktionierte wirklich gut.

1
HodlDwon

Ich weiß, dass dies eine alte Frage ist, aber keine der Antworten funktionierte für mich, weil ich die Zelle verlässlich (immer in der Lage) setzen wollte, wenn möglicherweise andere Ereignisse wie Toolbar-Button-Klicks, Menüauswahlen usw. ausgeführt wurden kann sich nach der Rückkehr dieser Ereignisse auf den Standardfokus auswirken. Ich brauchte einen Timer und rief an. Der folgende Code befindet sich in einer neuen Komponente, die von DataGridView abgeleitet ist. Mit diesem Code kann ich einfach einfach myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName); aufrufen, wenn ich willkürlich festlegen möchte, dass eine Zelle mit Datenbindung in den Bearbeitungsmodus versetzt wird (vorausgesetzt, die Zelle befindet sich nicht im ReadOnly-Modus).

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