Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Pager- und Footerzeilen des DataGrid erweitern

Geschrieben von: Alexander Zeitler
Kategorie: .NET Fu

Der Pager des DataGrids bietet standardmäßig nur zwei Arten der Formatierung: Seitenzahlen und "Symbole" zum Blättern ohne Angabe der Seitenzahlen. Ähnlich langweilig gestaltet sich der Footer - im Normalfall ist er nämlich leer, obwohl er sich gerade bei DataGrids für zB Summierung einzelner Spalten eignet.

Die in diesem .NET Fu vorgestellte Lösung wird so aussehen:

Die Lösung: Pager

Anwenderfreundlicher wäre ein Pager schon alleine durch die Tatsache, daß vor den Seitenzahlen das Wort "Seite" erscheint, damit der User überhaupt weiß, daß es sich um einen Pager mit mehreren Ergebnisseiten handelt.

Die Umsetzung ist relativ einfach. Ausgehend von der Tatsache, daß das Paging im DataGrid mittels AllowPaging bereits aktiviert ist, brauchen wir nur eine Möglichkeit, HTML-Elemente bzw. Text in den erzeugten DataGrid-HTML-Output einzubauen. Hierzu bietet sich das Event OnItemCreated unseres DataGrids an - idealerweise müssen wir uns hierbei nicht einmal durch HTML-Code wühlen, sondern bekommen eine einfach zu bearbeitende Control-Collection. Die Umsetzung ist jetzt fast nur noch Formsache:

private void ItemCreated(object sender, DataGridItemEventArgs e)
{
  if(e.Item.ItemType==ListItemType.Pager)
  {
    Label lblPager = new Label();
    lblPager.Text = "Seite " + lblPager.Text;
    e.Item.Controls[0].Controls.AddAt(0,lblPager);
  }
}

Nach einer Prüfung, ob das aktuelle Item der Pager ist, setzen wir einfach einen neuen Label an den Anfang der Controls-Collection des Pagers, welcher den Text "Seite:&nbsp" beinhaltet. Direkt im Anschluß an diesen folgen die Label- und LinkButton-Controls, welche die Seitenzahlen ausgeben.

Die Lösung: Footer

Wie eingangs bereits erwähnt, ist der Footer standardmäßig zum einen leer und zum anderen auch deaktiviert. Letzteres ändern wir sofort durch ein

this.DataGrid1.ShowFooter = true;

Den jetzt gewonnen freien Platz nutzen wir, um die Abfrage "Product Sales for 1995" aus der bekannten "Northwind"-Datenbank im DataGrid über mehrere Seiten verteilt darzustellen und an jedem Seitenende - eben in jenem Footer - den Übertrag der jeweiligen Umsätze für diese Seite darzustellen. Außerdem erweitern wir die Lösung noch dahingehend, daß wir auf der letzten Seite die Gesamtsumme präsentieren.

Die Herangehensweise ist ähnlich wie beim Pager, allerdings nutzen wir hier das Event OnItemDataBound.

Der erste Schritt ist die Generierung der Zwischensummen der einzelnen Seiten. Hierzu ist es notwendig, die Werte der einzelnen DataGridItems zu addieren. Zunächst ist also zu prüfen, ob das aktuelle Item ein Item bzw. AlternatingItem darstellt. Ist dies der Fall, werden die Werte aus der Datenquelle anhand des DataSetIndex' des aktuellen Items gelesen:

private void ItemDataBound(object sender, DataGridItemEventArgs e)
{
 if((e.Item.ItemType==ListItemType.Item)||(e.Item.ItemType==ListItemType.AlternatingItem))
 {
   lumpSum += 
      Double.Parse((this.ReadDataFromDB().Tables[0].Rows[e.Item.DataSetIndex][2].ToString()));
 }
}

"lumpSum" ist als öffentliche Variable vom Typ double innerhalb der Page-Klasse zu deklarieren:

public double lumpSum;

Der Weg über die Datenquelle erscheint zunächst umständlicher als z.B. die aktuellen Zellinhalte des DataGrids mittels Replace zu bearbeiten (in diesem Falle, um das Währungssymbol zu eliminieren) und zu addieren. Doch wie wir alle wissen, finden sich selten zwei Server mit absolut identischen Konfigurationen - die nächste Exception wegen fehlerhafter Inputstrings bei Double.Parse ist somit vorprogrammiert.

Nachdem wir nun die Summe ermittelt haben, müssen wir diese noch in die entsprechende Footerzelle des DataGrids schreiben. Diese Zellen lassen sich über einen nullbasierenten Index ansprechen. In unserem Fall handelt es sich um die dritte Spalte, somit wäre der gesuchte Index "2". Zu beachten ist hierbei, daß evtl. ausgeblendete Spalten (Visible=false) ebenfalls zu zählen sind. Die Zelle des Footers steht direkt als Objekt zur Verfügung und kann über die .Text-Eigenschaft den ermittelten und als Währung formatierten Wert von "lumpSum" aufnehmen (das Ganze findet nach wie vor in ItemDataBound statt).

if(e.Item.ItemType==ListItemType.Footer)
{
  e.Item.Cells[2].HorizontalAlign = HorizontalAlign.Right;
  e.Item.Cells[2].Text = "Übertrag: " + string.Format("{0:c}",lumpSum);
}

Schließlich fehlt uns nur noch die Ausgabe der Endsumme auf der letzten Seite. Hierzu müssen wir zunächst herausfinden, ob wir uns auf der letzten Seite befinden. Dies geschieht, indem wir die Anzahl der Datensätze in der Datenquelle durch die Seitengröße dividieren. Der Ganzzahlanteil stellt den Index der letzten Seite dar. Tritt der Sonderfall ein, daß der letzte Datensatz die letzte Seite genau ausfüllt, ist der Index um 1 zu minimieren, da sonst der Index eine Seite zuviel "produzieren" würde. Die wiederum würde dazu führen, daß auf unserer letzten Seite keine Endsumme erscheint.

Entspricht der ermittelte Index der letzten Seite "lastPageIndex" dem Index der aktuellen Seite, sind wir auf der letzten Seite gelandet. Jetzt müssen wir nur noch die Werte der Datenquelle aufsummieren und ähnlich wie beim Übertrag an unseren Footer anfügen:

DataSet dsSales = this.ReadDataFromDB();
int lastPageIndex = dsSales.Tables[0].Rows.Count/DataGrid1.PageSize;
if(dsSales.Tables[0].Rows.Count%DataGrid1.PageSize==0)
	lastPageIndex--;
if(lastPageIndex==DataGrid1.CurrentPageIndex)
{
	double totalLumpSum = 0;
	foreach(DataRow dr in this.ReadDataFromDB().Tables[0].Rows)
	{
		totalLumpSum += double.Parse(dr["ProductSales"].ToString());
	}
	e.Item.Cells[2].Text += 
		"<br>Endsumme:&nbsp;" + string.Format("{0:c}",totalLumpSum);
}

Somit ergibt sich für die hier vorgestellten Implementierungen im Gesamten also folgender Code (für den leichteren Überblick):

public double lumpSum;
private void ItemCreated(object sender, DataGridItemEventArgs e)
{
  if(e.Item.ItemType==ListItemType.Pager)
  {
    Label lblPager = new Label();
    lblPager.Text = "Seite&nbsp;" + lblPager.Text;
    e.Item.Controls[0].Controls.AddAt(0,lblPager);
  }
}

private void ItemDataBound(object sender, DataGridItemEventArgs e)
{
  if((e.Item.ItemType==ListItemType.Item)||(e.Item.ItemType==ListItemType.AlternatingItem))
  {
    lumpSum = lumpSum + 
     Double.Parse((this.ReadDataFromDB().Tables[0].Rows[e.Item.DataSetIndex][2].ToString()));
  }

  if(e.Item.ItemType==ListItemType.Footer)
  {
    e.Item.Cells[2].HorizontalAlign = HorizontalAlign.Right;
    e.Item.Cells[2].Text = "Übertrag:&nbsp;" + string.Format("{0:c}",lumpSum);
    DataSet dsSales = this.ReadDataFromDB();
    int lastPageIndex = dsSales.Tables[0].Rows.Count/DataGrid1.PageSize;
    if(dsSales.Tables[0].Rows.Count%DataGrid1.PageSize==0)
      lastPageIndex-- ;
    if(lastPageIndex==DataGrid1.CurrentPageIndex)
    {
      double totalLumpSum = 0;
      foreach(DataRow dr in this.ReadDataFromDB().Tables[0].Rows)
      {
        totalLumpSum += double.Parse(dr["ProductSales"].ToString());
      }
      e.Item.Cells[2].Text += 
        "<br>Endsumme:&nbsp;" + string.Format("{0:c}",totalLumpSum);
    }
  }
}

Ein funktionsfähiges Beispiel dieser Implementierung finden Sie hier.

Schlußbemerkung

Dieser Artikel hat gezeigt, wie leicht sich die scheinbar "statischen" Daten im DataGrid auch nachträglich modifizieren lassen. Natürlich bietet diese Implementierung Potential für weitere Verbesserungen - so werden Sie sicherlich die Daten aus Performancegründen nicht bei jedem Durchlauf von ItemDataBound aus der Datenbank lesen.

Eine weitere interessante Aufgabe, die auf dieser Lösung basiert, wäre beispielsweise den Übertrag der vorhergehenden Seiten mit dem Übertrag der aktuellen Seite zu kumulieren.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Das ASP.NET DataGrid selbst erweitern
DataGrid - Daten bearbeiten leicht gemacht
Einträge numerieren im DataGrid
MouseOver-Effekte beim DataGrid
Vergleich von DataGrid, DataList und Repeater-Control - was verwende ich wann?
Zahl, Datum und Währung korrekt formatiert ausgeben

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.