web-dev-qa-db-fra.com

Datagridview: Comment définir une cellule en mode édition?

Je dois définir par programme une cellule en mode édition. Je sais que définir cette cellule sur CurrentCell puis appeler la méthode BeginEdit (bool) devrait se produire, mais dans mon cas, cela ne se produit pas.

Je souhaite vraiment que, avec mon DGV à plusieurs colonnes, l'utilisateur puisse SEULEMENT sélectionner et éditer les deux premières. Les autres colonnes sont déjà en lecture seule, mais l'utilisateur peut les sélectionner et c'est ce que je ne veux pas.

Alors je pensais, dire à l'utilisateur de TAB chaque fois qu'il a fini d'écrire sur la cellule, puis sélectionnez la deuxième cellule, puis onglet à nouveau et il sélectionne et commence à éditer la première cellule de la ligne suivante.

Comment puis-je faire ceci?

28
josecortesp

Définir CurrentCell puis appeler BeginEdit(true) me convient bien.

Le code suivant montre un eventHandler pour l'événement KeyDown qui définit une cellule pour être modifiable. 

Mon exemple ne met en œuvre que l’un des raccourcis clavier nécessaires, mais en théorie, les autres doivent fonctionner de la même manière. (et je règle toujours la cellule [0] [0] pour qu'elle soit éditable, mais toute autre cellule devrait fonctionner)

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

Si vous ne l’aviez pas encore trouvée auparavant, DataGridView FAQ est une excellente ressource, écrite par le gestionnaire de programmes pour le contrôle DataGridView, qui couvre la plupart des tâches que vous pourriez souhaiter effectuer avec le contrôle.

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

Eh bien, je vérifierais si l’une de vos colonnes est définie sur ReadOnly. Je n'ai jamais eu à utiliser BeginEdit, mais il existe peut-être une utilisation légitime. Une fois que vous avez terminé dataGridView1.Columns[".."].ReadOnly = False;, les champs qui ne sont pas ReadOnly doivent être modifiables. Vous pouvez utiliser l'événement DataGridView CellEnter pour déterminer quelle cellule a été entrée , puis activer l'édition sur ces cellules après avoir passé l'édition des deux premières colonnes au groupe de colonnes suivant et désactiver l'édition sur les deux dernières colonnes. .

2
user195488

Je sais que cette question est assez ancienne, mais je me suis dit que je partagerais un code de démonstration que cette question m'a aidé.

  • Créer un formulaire avec une Button et une DataGridView
  • Enregistrer un événement Click pour button1
  • Enregistrez un événement CellClick pour DataGridView1
  • Définissez la propriété EditMode de DataGridView1 sur EditProgrammatically
  • Collez le code suivant dans 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);
                }
            }
        }
    }
}

Notez que les numéros d'index des colonnes peuvent changer à partir d'appuis multiples du premier bouton. Je me réfère donc toujours aux colonnes par leur nom, pas leur valeur d'index. J'avais besoin d'intégrer la réponse de David Hall à ma démo qui comportait déjà des ComboBox pour que sa réponse fonctionne vraiment bien.

1
HodlDwon

Je sais que c’est une vieille question, mais aucune des réponses n’a fonctionné pour moi, car je souhaitais définir de manière fiable (toujours pouvoir peut affecter la mise au point par défaut après le retour de ces événements. J'ai fini par avoir besoin d'une minuterie et d'invoquer. Le code suivant est dans un nouveau composant dérivé de DataGridView. Ce code me permet simplement d'appeler myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName); chaque fois que je souhaite définir de manière arbitraire une cellule liée aux données en mode édition (en supposant que la cellule est en mode Non en lecture seule).

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