Copy and Paste into DataGridView Cells, C #

1

I am trying to copy the value of a celda or several and to paste it to another (%) celda(s) . I currently have this basic method that works.

myDataGrid.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;

Datagridview KeyDown event:

if (e.Control && e.KeyCode == Keys.C)
{
   DataObject objeto_datos = myDataGrid.GetClipboardContent();
   Clipboard.SetDataObject(objeto_datos);
   e.Handled = true;
}
else 
if (e.Control && e.KeyCode == Keys.V)
{
    string texto_obtenido = Clipboard.GetText();
    string[] lineas = texto_obtenido.Split('\n');
    int fila = myDataGrid.CurrentCell.RowIndex;
    int columna = myDataGrid.CurrentCell.ColumnIndex;
    string[] celdas = lineas[0].Split('\t');
    int celdas_seleccionadas = celdas.Length;

    for (int indice = 0; indice < celdas_seleccionadas; indice++)
    {
         dgrid_hoja_horas[columna, fila].Value = celdas[indice];
         columna++;
    }
}
  

Being a very basic method, certain controls and validations are missing:

  • I need to avoid pasting data into cells ReadOnly .
  • The celda should only accept the pasting of data, if the copied data matches the value format of the cell . Formats: ( Datetime , Decimal , String ...). (Otherwise show some exception).
  • I use this method in different forms so it would be easier to create a function and not have to duplicate the code .
  

Note: I know that this topic can be considered broad, but I would accept any solution that you can offer me.

I use: Visual Studio 2010 and .NET Netframework 4

Edited:

  

Download Sample Code: CopyPegarDatagridview.zip Google Drive Link, Inside there is a TXT file read it please.

    
asked by J. Rodríguez 04.01.2018 в 22:49
source

2 answers

0

I have solved it in case someone else needs something similar here is the answer:

  

I found this example of "codeproject" from which I modified what I needed to use it as I want to create the event to use in different datagrids.

Copy function:

public void copiar_portapapeles(DataGridView datagrid)
{
     DataObject objeto_datos = datagrid.GetClipboardContent();
     Clipboard.SetDataObject(objeto_datos);
}

Paste function:

public void pegar_portapapeles(DataGridView datagrid)
{
      try
      {
           string texto_copiado = Clipboard.GetText();
           string[] lineas = texto_copiado.Split('\n');
           int error = 0;
           int fila = datagrid.CurrentCell.RowIndex;
           int columna = datagrid.CurrentCell.ColumnIndex;
           DataGridViewCell objeto_celda;

           foreach (string linea in lineas)
           {
               if (fila < datagrid.RowCount && linea.Length > 0)
               {
                   string[] celdas = linea.Split('\t');

                   for (int indice = 0; indice < celdas.GetLength(0); ++indice)
                   {
                       if (columna + indice < datagrid.ColumnCount)
                       {
                          objeto_celda = datagrid[columna + indice, fila];

                          //Mientras celda sea Diferente de ReadOnly
                          if (!objeto_celda.ReadOnly)
                          {
                              if (objeto_celda.Value.ToString() != celdas[indice])
                              {
                                  objeto_celda.Value = Convert.ChangeType(celdas[indice], objeto_celda.ValueType);
                              }
                          }
                          else
                          {
                             // solo intercepta un error si los datos que está pegando es en una celda de solo lectura.
                             error++;
                          }
                     }
                     else
                     { break; }
                }
                 fila++;
           }
           else
           { break; }

           if (error > 0)
              MessageBox.Show(string.Format("{0}  La celda no puede ser actualizada, debido a que la configuración de la columna es de solo lectura.", error),
                                        "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (FormatException fexcepcion)
            {
                MessageBox.Show("Los datos que pegó están en el formato incorrecto para la celda." + "\n\nDETALLES: \n\n" + fexcepcion.Message,
                                "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
        }

Datagridview KeyDown event:

public void datagrid_KeyDown(DataGridView datagrid, object sender, KeyEventArgs e)
{
     if (e.Control && e.KeyCode == Keys.C)
     {
         copiar_portapapeles(datagrid);
         e.Handled = true;
     }
     else
     if (e.Control && e.KeyCode == Keys.V) 
     {
         pegar_portapapeles(datagrid);
     }
 }

However I still have a doubt, if for example I have two columns Decimal A and B in which I must validate that the value of B should not be less than the value of A or the value of A should not Be greater than the value of B , this validation is done in the Event CellEndEdit , so when the data is pasted it does not validate this information because this event does not trigger.

What should I do to solve it? .

  

If someone does it with a different method please post your answer.

    
answered by 05.01.2018 / 19:20
source
0

The response of J. Rodríguez is good and perfectly functional. But ... it has a "but":

At least when cells are pasted from Excel to the datagrid. In that case in the last cell of each row the pasted value includes a character '\ r'. This may go unnoticed in many cases. But it was a problem for me. Fortunately, the solution is simple. The code is all identical except a single line that has been added. That is the only thing that must be done; add that line:

public void pegar_portapapeles(DataGridView datagrid)
{
  try
  {
       string texto_copiado = Clipboard.GetText();
       string[] lineas = texto_copiado.Split('\n');
       int error = 0;
       int fila = datagrid.CurrentCell.RowIndex;
       int columna = datagrid.CurrentCell.ColumnIndex;
       DataGridViewCell objeto_celda;

       foreach (string linea in lineas)
       {
           if (fila < datagrid.RowCount && linea.Length > 0)
           {
               string[] celdas = linea.Split('\t');

               for (int indice = 0; indice < celdas.GetLength(0); ++indice)
               {
                   if (columna + indice < datagrid.ColumnCount)
                   {
                      objeto_celda = datagrid[columna + indice, fila];

                      //Mientras celda sea Diferente de ReadOnly
                      if (!objeto_celda.ReadOnly)
                      {
                          if (objeto_celda.Value.ToString() != celdas[indice])
                          {
                              objeto_celda.Value = Convert.ChangeType(celdas[indice], objeto_celda.ValueType);
                              //A continuación la linea añadida para eliminar los '\r'. De paso, y por si acaso en algún contexto ocurre, tambien los: '\t' y '\n'
                                  objeto_celda.Value = objeto_celda.Value.ToString().Trim(new Char[] { '\t', '\n', '\r' });
                              // Fin linea añadida
                          }
                      }
                      else
                      {
                         // solo intercepta un error si los datos que está pegando es en una celda de solo lectura.
                         error++;
                      }
                 }
                 else
                 { break; }
            }
             fila++;
       }
       else
       { break; }

       if (error > 0)
          MessageBox.Show(string.Format("{0}  La celda no puede ser actualizada, debido a que la configuración de la columna es de solo lectura.", error),
                                    "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
        catch (FormatException fexcepcion)
        {
            MessageBox.Show("Los datos que pegó están en el formato incorrecto para la celda." + "\n\nDETALLES: \n\n" + fexcepcion.Message,
                            "ADVERTENCIA", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }
    }
    
answered by 30.05.2018 в 16:24