DataGridView

De Banane Atomic
Révision datée du 12 avril 2020 à 12:48 par Nicolas (discussion | contributions)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigationAller à la recherche

Coller

  • Ajouter un ContextMenuStrip à la Form.
  • Ajouter un ToolStripMenuItem au ContextMenuStrip. Renseigner la propriété ShortcutKeys.
  • Associer la propriété ContextMenuStrip de la DataGridView au ContextMenuStrip précédemment créé.
Csharp.svg
// Méthode associée au clique sur le ToolStripMenuItem
private void tsmiPaste_Click(object sender, EventArgs e)
{
    // si aucune cellule n'est sélectionnée on ne colle pas, car on ne sait pas ou commencer le collage.
    if (dgv.SelectedCells == null || dgv.SelectedCells.Count < 1)
    {
        return;
    }

    // récupération du contenu du presse papier
    string clipboardText = Clipboard.GetText();

    // séparation par lignes et suppression des lignes vides
    string[] clipboardLines = clipboardText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

    string[][] clipboardMatrix = new string[clipboardLines.Length][];
    for (int i = 0; i < clipboardLines.Length; i++)
    {
        var elements = clipboardLines[i].Split('\t');
        clipboardMatrix[i] = new string[elements.Length];
        for (int j = 0; j < elements.Length; j++)
        {
            clipboardMatrix[i][j] = elements[j];
        }
    }

    // paste from the first selected cell
    var selectedCell = dgv.SelectedCells[0];
    for (int i = 0; i < clipboardMatrix.Length; i++) // i: lines
    {
        int hiddenColumnOffset = 0; // for hidden columns
        for (int j = 0; j < clipboardMatrix[i].Length; j++) // j: columns
        {
            var currentCell = dgv[selectedCell.ColumnIndex + j + hiddenColumnOffset, selectedCell.RowIndex + i];

            // if you selected an entire row, don't treat the row header
            if (j == 0 && !currentCell.Visible && dgv.SelectedRows.Count > 0)
            {
                continue;
            }

            while (!currentCell.Visible) // for hidden columns
            {
                hiddenColumnOffset++;
                currentCell = dgv[selectedCell.ColumnIndex + j + hiddenColumnOffset, selectedCell.RowIndex + i];
            }

            try
            {
                currentCell.Value = Convert.ChangeType(clipboardMatrix[i][j], currentCell.ValueType);
            }
            catch { }
        }                
    }
}

Gestion des exceptions

Csharp.svg
// Capture toutes les exceptions générée par la DataGridView
private void dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
    // Affiche une icône dans l'en-tête de la ligne avec le message en ToolTip.
    dgvOverrode.Rows[e.RowIndex].ErrorText = "wrong value";
    //dgvOverrode.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "wrong value";

    // annule l'exception
    e.ThrowException = false;
}

// Efface les messages d'erreur une fois qu'une bonne valeur est saisie
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    dgvOverrode.Rows[e.RowIndex].ErrorText = String.Empty;
    //dgvOverrode.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = String.Empty;
}

Liaison avec une DataTable

La DataTable et la DataGridView sont en permanence synchronisés.

Csharp.svg
var dt = new DataTable();
dt.Columns.Add("Colonne");

var dgv = new DataGridView();
dgv.DataSource = dt;

// l'ajout de ligne par le code doit se faire sur la DataTable et non sur la DataGridView
dt.Rows.Add("1");

EditMode

EditOnKeyStrokeOrF2 : Mode par défaut, il faut double-cliquer sur une cellule pour l’éditer.
EditOnEnter : Dans ce mode il suffit de cliquer sur la cellule pour l’éditer. Par contre un clique sur le header d’une ligne édite la première cellule, ce qui empêche de supprimer la ligne.
EditOnEnter et suppression de ligne:

Csharp.svg
private void DGV_MouseClick(object sender, MouseEventArgs e)
{
    DataGridView.HitTestInfo hitInfo = this.DGV.HitTest(e.X, e.Y);
    if (hitInfo.Type == DataGridViewHitTestType.RowHeader)
    {
        this.DGV.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
        this.DGV.EndEdit();
    }
    else
    {
        this.DGV.EditMode = DataGridViewEditMode.EditOnEnter;
    }
}

Tester les données des cellules dès leurs saisies

La validation bloque l’utilisateur tant qu’il n’a pas saisie de valeur valide et affiche un message d’erreur.

Csharp.svg
private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
  DataGridView dgv = (DataGridView)sender;
  if (dgv.Columns[e.ColumnIndex] == "ColumnName")
  {
      if (string.IsNullOrEmpty(e.FormattedValue.ToString())
      {
          dgv.Rows[e.RowIndex].ErrorText = "Cell must not be empty";
          e.Cancel = true;
      }
    }
}
private void cduDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    ((DataGridView)sender).Rows[e.RowIndex].ErrorText = String.Empty;
}

Tri en fonction d’une colonne

Csharp.svg
dgv.Sort(dgv.Columns[1], ListSortDirection.Descending);

Propriété intéressantes de l'interface

  • Alignement :
    • DefaultCellStyle.Alignement = MiddleCenter
    • ColumnHeadersDefaultCellStyle = MiddleCenter
  • Taille des colonnes : AutoSizeColumnsMode = DisplayCells
  • Cacher la première colonne : RowHeadersVisible = false
  • Empêcher la redimension : AllowUserToResize… = false