Das Datagrid in ASP .NET erlaubt, mit quasi zwei Zeilen Code vollautomatisch die Listendarstellung von Daten. Auch tiefergehende Funktionen wie Änderungen am Design sind vorhanden und leicht über die Templates zu nutzen. Aber wie so oft stößt man bei den "vollautomatischen Assistenten" irgendwann an Grenzen.
Auf den ersten Blick ist das Ändern, der Hintergrundfarbe einer einzelnen Zelle abhängig von deren Inhalt ein schon ein Grenzübertritt. So sollten z.B. negative Zahlen rot dargestellt werden. Die geschieht über das Proberty backcolor, das auf den ersten Block nicht eistiert. Zuerst muss man deshalb die entsprechende Spalte in eine Template Column umwandeln.
Das kann über den visuellen Proberty Builder geschehen. Dies hat zwar eigentlich einen anderen Sinn, tuts für unseren Zweck aber auch.
So erhält man in Itemtemplate ein Label, das wiederum die Eigenschaft BackColor besitzt, auf die wir uns gleich stürzen werden.
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.preis") %>' BackColor="red"> </asp:Label> |
Nun muss noch die Abhängigkeit vom Wert der Zelle erzeugt werden. Hier zeigt sich, das jeder naheliegende Ansatz scheitert. Das einzige, was zuverlässig, auch für die verschiedenen Probertys funltioniert ist, eine Funktion (CheckColor) zu binden. Diese "CheckColor" benötigt als Parameter den Wert aus der Tabelle, der über den Databinder abrufbar ist.
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.preis") %>' BackColor=<%#checkColor((int)DataBinder.Eval(Container.DataItem, "preis") ) %>'> </asp:Label> |
In der Funktion liegt noch ein Stolperstein. Zuerst würde man sicher versuchen die Farbe als Typ String zurückzugeben.... Mitnichten, es wird der Datentyp Color erwartet.
Public Function checkColor(ByVal wert As Integer) As Color If wert < 3 Then Return Color.Red Else Return Color.Blue End If End Function |
Ebenso erwartet z.B. die Eigenschaft Visible ein True oder False im Boolschen Format.
Bild1:
Obwohl diese Lösung sehr einfach ist, gibt es noch eine zweite über die man doch Bescheid wissen sollte.
Dazu werfen wir einen Blick auf die Events des Grids.
Methode 2
Jedesmal, wenn ein neuer Datensatz an eine Zelle des Grid gebunden wird, wird das Event Itemdatabound aufgerufen. Hier kann dann auf das Design oder den Inhalt einfluss genommen werden. Über e lässt sich die per Item auf die einzelnen Zellen zugreifen. An dieser Stelle ist dies nur über den Index zulässig.
Private Sub dgResult_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgResult.ItemDataBound If CInt(e.Item.Cells(2).Text) > 2 Then e.Item.Cells(2).BackColor = Color.Red Else e.Item.Cells(2).BackColor = Color.Blue End If End Sub |
In diesem Code steckt eine kleine Fehlerquelle. Wenn eine Überschrift vorhanden ist, wird ein Fehler geworfen, da Text nicht nach Int geparst werden kann. Relativ einfach lässt sich das per Try Catch abfangen.
Der Vorteil der zweiten Methode liegt darin, das im Grid Design nicht eingegriffen werden muss. Man kann mit den Autogenerierten Spalten arbeiten oder Columns definieren.
<asp:BoundColumn DataField="overall"></asp:BoundColumn> |
Die zweite Methode hat also keinen Code in der ASPX Seite und entspricht eventuell mehr der Idee von ASP .NET.