DataGrid com somatório no rodapé – Parte II
Segundo Passo: Vinculável a qualquer DataSource
Não é fantástico? não escrevemos uma única linha de código no code behind do WebForm e estamos obtendo sum/count/average no Footer. Podemos fazer o mesmo com a coluna Bônus apenas mudando o tipo da coluna SumColumn. Porém temos apenas um pequeno problema. Este controle trabalha bem caso o DataSource do DataGrid for DataTable ou DataReader. Caso tentarmos utilizar objetos personalizados Array ou ArrayList, provavelmente obteremos uma mensagem do tipo:
Figura 4.
Temos que achar uma maneira de manipular qualquer tipo de DataSource. Hmmm... Que tal utilizar a classe PropertyDescriptor do namespace System.ComponentModel para obter ao valor em lugar do objeto subjacente. Atualizamos a seguinte linha de CellItemDataBound:
dValue = DGI.DataItem(DataField)
para a linha abaixo:
dValue = Me.GetUnderlyingValue(dataItem)
e adicionamos um novo método GetUnderlyingValue a nossa classe.
Protected Function GetUnderlyingValue(ByVal dataItem As Object) As Decimal
Dim boundFieldDesc As PropertyDescriptor = _
TypeDescriptor.GetProperties(dataItem).Find(Me.DataField, True)
If(boundFieldDesc Is Nothing) Then
Throw New HttpException("Field Not Found: " + Me.DataField)
End If
Dim dValue As Object = boundFieldDesc.GetValue(dataItem)
Return Decimal.Parse(dValue.ToString())
End Function
Ao invés de apenas puxar o valor do DataItem, estamos dependendo do Método GetUnderlyingValue para obter o valor do DataItem, o qual, por sua vez, utiliza a classe TypeDescriptor para verificar se exista o objeto subjacente DataField. Se for bem sucedido, retornará o valor ao método chamador, caso contrário, levantará Exception. Agora podemos verificar a saída com (quase) todos os tipos de DataSource.
Terceiro Passo: Saída Personalizável
Tudo parece estar de acordo agora, porém não há nenhum controle na saída. E caso desejemos mostrar apenas a soma (nenhuma média e nenhuma contagem)? Alguma outra pessoa desejará mostrar a soma e a média. Existem diferentes possibilidades, portanto, deve haver alguma forma de personalizar às saídas como desejado. Vejamos o que podemos fazer:
#Region " Attributes "
Private internalSum As Decimal
Private internalCount As Integer
Private _ShowSum As Boolean = True
Private _ShowCount As Boolean = True
Private _ShowAverage As Boolean = True
#End Region
#Region " Properties "
Public Property ShowSum() As Boolean
Get
Return _ShowSum
End Get
Set(ByVal Value As Boolean)
_ShowSum = Value
End Set
End Property
Public Property ShowCount() As Boolean
Get
Return _ShowCount
End Get
Set(ByVal Value As Boolean)
_ShowCount = Value
End Set
End Property
Public Property ShowAverage() As Boolean
Get
Return _ShowAverage
End Get
Set(ByVal Value As Boolean)
_ShowAverage = Value
End Set
End Property
#End Region
Expusemos três propriedade públicas, isto é, ShowSum, ShowCount e ShowAverage em nossa classe SumColumn. Podemos utilizar estas propriedade no .aspx para personalizar às saídas. Por exemplo;