DataGrid com somatório no rodapé – Parte II

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (0)  (0)

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

 

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.

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?