DataGrid com somatório no rodapé – Parte II

Veja a segunda parte do artigo, que mostra como criar somatórios no rodapé do DataGrid. Acesso exclusivo para Assinantes.

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;

 

DataField="Salary" HeaderText="Salary">

 

ou

 

DataField="Salary" HeaderText="Salary">

 

Internamente em nossa classe, podemos verificar os valores das propriedades no método CellItemDataBound exposto para personalizar às saídas da forma desejada.

 

Case ListItemType.Footer

If Me._ShowSum = True Then

cell.Text = "Sum : " & Me.FormatDataValue(internalSum) & "
"

End If

 

If Me._ShowCount = True Then

cell.Text += "Count : " & internalCount & "
"

End If

 

If Me._ShowAverage = True Then

cell.Text += "Average : " & Me.FormatDataValue(internalSum / internalCount)

End If

End If

 

Se atualizarmos o código e o .aspx, poderemos obter as seguintes saídas:

 

 

Figura 5.

Quarto Passo: Ajustando as Saídas em Tempo de Design

Sim, sabemos que agora está se sentindo sonolento, porém me dê apenas mais cinco minutos. Se não estiver interessado em alterar as saída em tempo de projeto, (isto é quando vemos o DataGrid em tempo de projeto utilizando o Visual Studio), então pode pular esta seção. Para aqueles que ainda estão lendo, verificar as alterações no código abaixo:

 

Case ListItemType.AlternatingItem, ListItemType.Item

 

If Me.DesignMode = False Then

dValue = Me.GetUnderlyingValue(dataItem)

.....

.....

cell.Text = Me.FormatDataValue(dValue)

Else

cell.Text = "SumColumn"

End If

 

Case ListItemType.Footer

If Me.DesignMode = False Then

If Me._ShowSum = True Then

.....

.....

End If

Else

cell.Text = "Total"

End If

 

Acho que o código é completamente auto-explicativo. Utilizamos simplesmente a propriedade DesignMode da classe base BoundColumn para ajustar as saídas de SumColumn em tempo de projeto.

 

 

Figura 6.

Conclusão

Agora já temos a nossa própria nova coluna SumColumn personalizada, derivada de BoundColumn, com a funcionalidade de mostrar os valores sum/average/count das colunas no footer do DataGrid. Este é apenas um exemplo de uma coluna DataGrid reutilizável e depende de você examinar suas próprias aplicações e aquilo que poderia realmente ser envelopado em uma coluna DataGrid personalizada.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados