Doppelte Zeilen in neues DataGridView übertragen  
Frank Dzaebel, erstellt am: 28.01.07, zuletzt geändert:  28.01.07
Kategorie: Implementation, .NET-Version: 2.0, [Download]

Doppelte Zeilen (mit gleichen Werten in einer auszuwählenden Spalte) werden im Code-Beispiel generisch in ein zweites DataGridView übertragen. Ein kleine Arbeitserleichterung für ähnliche Aufgaben. Das Fenster wird im Beispiel über Windows Vista dargestellt.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

namespace DoublePattern
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      FülleDaten(dgvGefunden);
      comboBoxSpalten.DataSource = columnNames;
    }

    string[] columnNames = {"Vorname", "Nachname", "Alter"};
    
    private void FülleDaten(DataGridView dgv)
    {
      DataTable dt = CreateDataTable(columnNames);
      DataRow dr = dt.NewRow();
      dt.Rows.Add(new object[] { "Jörg", "Ross", "32" });
      dt.Rows.Add(new object[] { "Eva", "Schmidt", "31" });
      dt.Rows.Add(new object[] { "Holger", "Behrens", "33" });
      dt.Rows.Add(new object[] { "Roland", "Schmidt", "75" });
      dt.Rows.Add(new object[] { "Johann", "Bertelsacker", "33" });
      dt.Rows.Add(new object[] { "Frank", "Schmidt", "43" });
      dt.Rows.Add(new object[] { "Helga", "Herrmann", "32" });
      dt.Rows.Add(new object[] { "Jochen", "Behrens", "33" });
      dgv.DataSource = dt;
    }
    
    private DataTable CreateDataTable(string[] spaltenNamen)
    {
      DataTable dt = new DataTable();
      foreach (string spaltenName in spaltenNamen)
        dt.Columns.Add(spaltenName);
      return dt;
    }
    
    private void btnDoppelte_Click(object sender, EventArgs e)
    {
      string spalte = comboBoxSpalten.SelectedItem.ToString();
      List<DataGridViewRow> doppelte = DoppelteZeilenInSpalte(dgvGefunden, spalte);
      if (doppelte.Count == 0)
        MessageBox.Show("Keine doppelten Werte in Spalte " + spalte + " vorhanden!");
      DataTable dt = ((DataTable)dgvGefunden.DataSource).Clone();
      DgvrListeInDataTable(doppelte, dt);
      dgvDoppelte.DataSource = dt;
    }

    private void DgvrListeInDataTable(List<DataGridViewRow> doppelte, DataTable dt)
    {
      foreach (DataGridViewRow dgvr in doppelte)
      {
        DataRow dr = dt.NewRow();
        foreach (DataColumn dc in dt.Columns)
          dr[dc.ColumnName] = dgvr.Cells[dc.ColumnName].Value;
        dt.Rows.Add(dr);
      }
    }

    private List<DataGridViewRow> DoppelteZeilenInSpalte(DataGridView dgvGefunden, string spaltenName)
    {
      List<DataGridViewRow> dbl = new List<DataGridViewRow>();
      Dictionary<string, DataGridViewRow> colVals = new Dictionary<string, DataGridViewRow>();
      List<DataGridViewRow> dblNulls = new List<DataGridViewRow>();
      
      foreach (DataGridViewRow dr in dgvGefunden.Rows)
      {
        if (dr.Cells[spaltenName].Value == null)
        {
          dblNulls.Add(dr); continue;
        }
        string spaltenWert = dr.Cells[spaltenName].Value.ToString();
        if (colVals.ContainsKey(spaltenWert))
        {
          if (!dbl.Contains(colVals[spaltenWert]))
            dbl.Add(colVals[spaltenWert]);
          colVals.Remove(spaltenWert);
          dbl.Add(dr);
        }
        colVals.Add(spaltenWert, dr);
      }

      if (dblNulls.Count >= 2)
        foreach (DataGridViewRow dgr in dblNulls)
          dbl.Add(dgr);

      return dbl;
    }
  }
}