DataGridView mit Fußzeile  
Frank Dzaebel, erstellt am: 24.2.2008, zuletzt geändert:  31.5.2009
Kategorie: C# Sprache, .NET-Version: 2.0, [C# Download]    [VB.NET Download]

Ein DataGridView mit Fußzeile, die automatisch int-Spalten aufsummiert, als anpassbares UserControl. Die Fußzeile verschiebt sich, wenn die horizontale ScrollBar des DataGridViews betätigt wird. Auch Rezise-Aktionen werden berücksichtigt. 



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

namespace DgvFooter2
{
  public partial class DgvFooter : UserControl
  {
    public DgvFooter()
    {
      InitializeComponent();
    }

    /// <summary>Ruft das obere DataGridView ab.</summary>
    [Description("Ruft das obere DataGridView ab.")]
    public DataGridView Dgv
    {
      get { return dgvHead; }
    }

    class HeadDgv : DataGridView
    {
      public HeadDgv()
      {
        this.HorizontalScrollBar.ValueChanged += new EventHandler(HorizontalScrollBar_ValueChanged);
        this.HorizontScrollBar = (HScrollBar)this.HorizontalScrollBar;
      }

      public HScrollBar HorizontScrollBar;

      public event EventHandler HScrollBarValueChanged;

      void HorizontalScrollBar_ValueChanged(object sender, EventArgs e)
      {
        HScrollBarValueChanged(HorizontalScrollBar, EventArgs.Empty);
      }
    }

    private void DgvFooter_Load(object sender, EventArgs e)
    {
      if (!DesignMode) lbFootTitel.Visible = false;
      dgvHead.Columns.CollectionChanged += new
        CollectionChangeEventHandler(Columns_CollectionChanged);
      dgvHead.ColumnWidthChanged += new DataGridViewColumnEventHandler(
        dgvHead_ColumnWidthChanged);
      dgvHead.CellValueChanged += new DataGridViewCellEventHandler(dgvHead_CellValueChanged);
      dgvHead.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dgvHead_DataBindingComplete);
      dgvHead.HScrollBarValueChanged += new EventHandler(dgvHead_HScrollBarValueChanged);
      dgvFoot.SelectionChanged += new EventHandler(dgvFoot_SelectionChanged);
      lblSumme.Location = new Point(dgvHead.Left, dgvHead.Top + dgvHead.Height);
    }

    void dgvFoot_SelectionChanged(object sender, EventArgs e)
    {
      if (dgvFoot.SelectedCells != null)
        if (dgvFoot.SelectedCells.Count > 0)
          dgvFoot.ClearSelection();
    }

    void dgvHead_HScrollBarValueChanged(object sender, EventArgs e)
    {
      DgvFooter_SizeChanged(this, EventArgs.Empty);
    }

    void dgvHead_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
      if (dgvFoot.Columns == null || dgvFoot.Columns.Count == 0) return;
      if (dgvFoot.Rows.Count == 0)
        dgvFoot.Rows.Add();
      foreach (DataGridViewColumn col in dgvHead.Columns)
        AlleZellenInFooterAddieren(col.Index);
    }

    void dgvHead_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
      if (dgvHead.Columns[e.ColumnIndex].ValueType == typeof(int))
        AlleZellenInFooterAddieren(e.ColumnIndex);
    }

    const int firstRow = 0;

    private void AlleZellenInFooterAddieren(int columnIndex)
    {
      if (dgvHead.Columns[columnIndex].ValueType != typeof(int)) return;
      int summe = 0;

      foreach (DataGridViewRow row in dgvHead.Rows)
      {
        object obj = row.Cells[columnIndex].Value;
        if (obj == null || obj == DBNull.Value) continue;
        summe += (int)row.Cells[columnIndex].Value;
      }
      dgvFoot[columnIndex, firstRow].Value = summe;
    }

    void dgvHead_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
    {
      dgvFoot.Columns[e.Column.DataPropertyName].Width = e.Column.Width;
    }

    DataGridViewColumn dgc;
    DataGridViewColumn col;

    void Columns_CollectionChanged(object sender, CollectionChangeEventArgs e)
    {
      switch (e.Action)
      {
        case CollectionChangeAction.Add:
          dgc = e.Element as DataGridViewColumn;
          if (dgc == null) return;
          col = new DataGridViewColumn(dgc.CellTemplate);
          col.Name = dgc.Name; col.DataPropertyName = dgc.DataPropertyName;
          col.ValueType = dgc.ValueType;
          dgvFoot.Columns.Add(col); break;

        case CollectionChangeAction.Remove:
          dgc = e.Element as DataGridViewColumn;
          col = dgvFoot.Columns[dgc.DataPropertyName];
          dgvFoot.Columns.Remove(col); break;

        default: dgvFoot.Invalidate(); break;
      }
    }

    private void DgvFooter_SizeChanged(object sender, EventArgs e)
    {
      HScrollBar hb = dgvHead.HorizontScrollBar;
      hb.Show();
      lblSumme.Location = new Point(dgvHead.Left, dgvHead.Top + dgvHead.Height);
      if (dgvHead.RowHeadersWidth != lblSumme.Width)
        if (dgvHead.RowHeadersWidth > lblSumme.MinimumSize.Width)
          lblSumme.Width = dgvHead.RowHeadersWidth;
        else
          lblSumme.Width = lblSumme.MinimumSize.Width;
      int horiOffset = (hb.Value - hb.Minimum);
      dgvFoot.Left = dgvHead.RowHeadersWidth - horiOffset;
      dgvFoot.Top = dgvHead.Top + dgvHead.Height;
      dgvFoot.Width = dgvHead.Width + horiOffset;
      if (hb.LargeChange + hb.Value > hb.Maximum)
        hb.Value = hb.Maximum - hb.LargeChange;
    }

    private void dgvHead_RowHeadersWidthChanged(object sender, EventArgs e)
    {
      DgvFooter_SizeChanged(this, EventArgs.Empty);
    }
  }
}