[C#] DataGridView Drag & Drop in eine Zeile (Row)

Im Beispiel liegen zwei DataGridViews auf einem Formular: gvSource und gvTarget. Die gewählte Zeile aus gvSource wird per Drag & Drop in gvTarget gezogen.

// Eigenschaften die gesetzt werden müssen
gvSource.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.AllowDrop = true;

// wenn im gvSource ein oder mehrere Zeilen markiert und der linke Mausbutton gedrückt gehalten wird
private void gvSource_CellMouseDown(object sender, MouseEventArgs e)
{
    // nur DragDrop initiieren, wenn Elemente aus dem Zellenbereich gewählt,
    // sonst gibt es Probleme beim Einstellen der Spaltenbreite per Maus
    if (e.RowIndex != -1)
    {
        if (gvSource.SelectedRows.Count > 0)
        {
            DragDropEffects dropEffect = gvSource.DoDragDrop(gvSource.SelectedRows, DragDropEffects.Copy);
        }
    }
}

// wenn die Maus mit den Objekten über gvTarget ist
private void gvTarget_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    DataGridViewSelectedRowCollection rows = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows != null)
    {
        e.Effect = DragDropEffects.Copy;
    }
}

// Objekte aus gvSource in gvTarget einfügen, Doppelungen vermeiden
private void gvTarget_DragDrop(object sender, DragEventArgs e)
{
	DataGridViewSelectedRowCollection rows_source = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

	if (rows_source != null)
	{
		Point p = gvTarget.PointToClient(new Point(e.X, e.Y));
		DataGridView.HitTestInfo info = gvTarget.HitTest(p.X, p.Y);

		if (info.RowIndex != -1 && info.ColumnIndex != -1)
		{
			foreach (DataGridViewRow rs in rows_source)
			{
				bool bFound = false;

				// prüfen, ob schon in der Liste
				foreach (DataGridViewRow row_target in gvTarget.Rows)
				{
					// Vergleich von Spalte mit Index 0, wenn gleich, dann schon vorhanden
					if (rs.Cells[0].Value.ToString() == row_target.Cells[0].Value.ToString())
					{
						bFound = true;
						break;
					}
				}

				// wenn noch nicht vorhanden, dann einfügen
				if (bFound == false)
				{
					DataGridViewRow rnew = new DataGridViewRow();
					rnew.CreateCells(gvTarget);

					// Indexe beachten, Spaltenanordnung von gvSource muss
					// nicht der von gvTarget entsprechen
					rnew.Cells[0].Value = rs.Cells[1].Value.ToString();
					rnew.Cells[1].Value = rs.Cells[2].Value.ToString();
					rnew.Cells[2].Value = rs.Cells[3].Value.ToString();

					gvTarget.Rows.Add(rnew);
				}
			}
		}
	}
}

[C#] DataGridView Drag & Drop (MultiSelect)

Im Beispiel liegen zwei DataGridViews auf einem Formular: gvSource und gvTarget. Die gewählten Zeilen (MultiSelect ist möglich) aus gvSource werden per Drag & Drop in gvTarget gezogen. Vorrausetzung ist hierbei, dass in beiden DataGridViews die gleichen Spalten vorhanden sind.

// Eigenschaften die gesetzt werden müssen
gvSource.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvSource.MultiSelect = true;
gvTarget.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
gvTarget.AllowDrop = true;

// wenn im gvSource ein oder mehrere Zeilen markiert und der linke Mausbutton gedrückt gehalten wird
private void gvSource_CellMouseDown(object sender, MouseEventArgs e)
{
    // nur DragDrop initiieren, wenn Elemente aus dem Zellenbereich gewählt,
    // sonst gibt es Probleme beim Einstellen der Spaltenbreite per Maus
    if (e.RowIndex != -1)
    {
        if (gvSource.SelectedRows.Count -> 0)
        {
            DragDropEffects dropEffect = gvSource.DoDragDrop(gvSource.SelectedRows, DragDropEffects.Copy);
        }
    }
}

// wenn die Maus mit den Objekten über gvTarget ist
private void gvTarget_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.None;

    DataGridViewSelectedRowCollection rows = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows != null)
    {
        e.Effect = DragDropEffects.Copy;
    }
}

// Objekte aus gvSource in gvTarget einfügen, Doppelungen vermeiden
private void gvTarget_DragDrop(object sender, DragEventArgs e)
{
    DataGridViewSelectedRowCollection rows_source = e.Data.GetData(typeof(DataGridViewSelectedRowCollection)) as DataGridViewSelectedRowCollection;

    if (rows_source != null)
    {
        foreach (DataGridViewRow rs in rows_source)
        {
            bool bFound = false;

            // prüfen, ob schon in der Liste
            foreach (DataGridViewRow row_target in gvTarget.Rows)
            {
                // Vergleich von Spalte mit Index 0, wenn gleich, dann schon vorhanden
                if (rs.Cells[0].Value.ToString() == row_target.Cells[0].Value.ToString())
                {
                    bFound = true;
                    break;
                }
            }

            // wenn noch nicht vorhanden, dann einfügen
            if (bFound == false)
            {
                DataGridViewRow rnew = new DataGridViewRow();
                rnew.CreateCells(gvTarget);

                rnew.Cells[0].Value = rs.Cells[0].Value.ToString();
                rnew.Cells[1].Value = rs.Cells[1].Value.ToString();
                rnew.Cells[2].Value = rs.Cells[2].Value.ToString();

                gvTarget.Rows.Add(rnew);
            }
        }
    }
}

[C#] DataGridView Zeile verschieben (move up/down)

// move up
private void btnUp_Click(object sender, EventArgs e)
{
    if (dataGridView1.SelectedCells.Count -> 0)
    {
        int idx = dataGridView1.SelectedCells[0].OwningRow.Index;

        if (idx -> 0)
        {
            int col = dataGridView1.SelectedCells[0].OwningColumn.Index;
                
            DataGridViewRowCollection rows = dataGridView1.Rows;
            DataGridViewRow row = rows[idx];
                
            rows.Remove(row);
            rows.Insert(idx - 1, row);

            dataGridView1.ClearSelection();
                
            dataGridView1.Rows[idx - 1].Cells[col].Selected = true;
        }
    }
}

// move down
private void btnDown_Click(object sender, EventArgs e)
{
    if (dataGridView1.SelectedCells.Count -> 0)
    {
        int idx = dataGridView1.SelectedCells[0].OwningRow.Index;

        if (idx < dataGridView1.Rows.Count)
        {
            int col = dataGridView1.SelectedCells[0].OwningColumn.Index;

            DataGridViewRowCollection rows = dataGridView1.Rows;
            DataGridViewRow row = rows[idx];

            rows.Remove(row);
            rows.Insert(idx + 1, row);

            dataGridView1.ClearSelection();

            dataGridView1.Rows[idx + 1].Cells[col].Selected = true;
        }
    }
}

[C#] DataGridView verwenden

  • DataGridView aus der Toolbox auf eine Form ziehen
  • rechts klicken und “Spalten bearbeiten …” wählen
  • ungebundene Spalte, Name “cCheck”, Typ “DataGridViewCheckBoxColumn”, Headertext “Check” hinzufügen
  • ungebundene Spalte, Name “cTime”, Typ “DataGridViewTextBoxColumn”, Headertext “Zeit” hinzufügen
  • ungebundene Spalte, Name “cValue”, Typ “DataGridViewTextBoxColumn”, Headertext “Wert” hinzufügen
  • ungebundene Spalte, Name “cUnit”, Typ “DataGridViewTextBoxColumn”, Headertext “Einheit” hinzufügen
  • Schließen
  • auf “Zeit” klicken und Eigenschaft Layout->Frozen auf true (fixiert Spalte “Zeit” beim Scrollen)
  • Ok zum Schließen
  • DataGridView Eigenschaften->AllowUserToAddRows = false
  • DataGridView Eigenschaften->AllowUserToDeleteRows = false
private void DataGridView()
{
    // Zeilen zum DataGridView hinzufügen
    for (int i = 1; i < 10; i++)
    {
        // neue Zeile erzeugen
        DataGridViewRow r = new DataGridViewRow();
        r.CreateCells(dataGridView1);

        // Zellwerte eintragen
        r.Cells[0].Value = true; // Check-Spalte
        r.Cells[1].Value = i.ToString();
        r.Cells[2].Value = (i * i).ToString();
        r.Cells[3].Value = "mm";

        // Zeile dem DataGridView hinzufügen
        dataGridView1.Rows.Add(r);
    }

    // Spaltenname von "Zeit" auf "Index" ändern
    dataGridView1.Columns[0].HeaderCell.Value = "Index";
    // Schrift ändern, siehe auch Eigenschaft ColumnHeadersDefaultCellStyle im Properties-Editor
    dataGridView1.Columns[0].HeaderCell.Style.Font = new Font("Microsoft Sans Serif", 9.75F, FontStyle.Bold);

    // Zugriff auf Zelle [0, 0]
    dataGridView1[0, 0].Value = "0.0";
    dataGridView1[0, 0].Style.ForeColor = Color.Fuchsia;
    dataGridView1[0, 0].Style.BackColor = Color.LightGreen;
}