WPF - Conversão e formatação de dados  - I


Neste artigo eu vou tratar da conversão de dados em aplicações WPF . Geralmente precisamos formatar os dados exibidos quando usamos o databinding pois na vinculação de dados comum a informação vem da fonte para a origem sem qualquer mudança. Se você estiver usando a vinculação two-way vai ter que fazer um conversor de forma a converter os dados informados pelo usuário em um formato apropriado ao objeto de origem.

A WPF permite que você realize estas duas tarefas através da criação de uma classe conversora de forma que ela formate a exibição no destino e , em caso de two-way binding, converta o novo valor informado no destino antes do mesmo ser aplicado a fonte.

Os conversores de valores (Value Converter) podem então ser considerados como uma peça muito importante na vinculação de dados no WPF podendo ser usados de diversas formas:

Formatando strings com o Conversor de valores

O conversor de valor (Value Converter) é uma ferramenta perfeita para formatar números que precisam ser exibidos como texto. Isto geralmente ocorre quando você precisa exibir valores monetários no formato da moeda local.

Então como podemos criar o tal conversor de valores ?

Para criar um conversor de valores, você precisa seguir 4 etapas:

Seguindo o roteiro você deverá incluir uma classe ao seu projeto nomeando-a [SourceType]To[TargetType]Converter , tornando-a pública e implementando a interface IvalueConverter conforme mostrado a seguir:

Public Class DecimaltoNumericConverter
         Implements IValueConverter
    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object
        '  faça a conversão de decimal para numérico
    End Function
    
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object
       '  faça a conversão de numérico para decimal
    End Function
End Class

A figura abaixo mostra o esquema de funcionamento do conversor de valor:

Para realizar as conversões e/ou formatações você deverá utilizar a formatação de strings disponível no Visual Studio.

No caso de uma conversão decimal -> valor monetário, por exemplo, você pode usar o método Decimal.ToString() especificando o formato moeda como "C" . Ex: Dim txtValor As String = decimalPrice.ToString("C")

Este código usa configurações de cultura que se aplicam a thread atual. Dessa forma um computador configurado para a região com um locale igual a en-US irá exibir os valores com o sinal da moeda local ou seja do dólar ($). Se você deseja outro resultado você deve especificar a cultura usando o método ToString() conforme a seguir:

Dim culture As New CultureInfo("en-US")
string txtValor = decimalPrice.ToString("C", culture)

Nas tabelas a seguir temos as opções mais comum que você poderá usar para formatação de valores numéricos e de datas:

Tabela 1 - Formatar de String para dados Numéricos

Tipo Formato String Exemplo
Currency C R$ 1.234,56
Cientifico (Exponencial) E 1.234.50E+004
Percentagem P 45,6%
Decima Fixo F? F3 = 123.400
F0 = 1234

Tabela 2 - Formatar de String para Datas e horas

Tipo Formato String Exemplo
Short Date d M/d/YYYY. Ex: 20/02/2010
Long Date D dddd, MMMM dd, yyyy. Ex: Quarta-feira , Janeiro 30, 2010
Month e Day M MMMM dd . Ex: Janeiro 30
Geral G M/d/yyyy HH:mm:ss aa. Ex: 10/30/2008 10:00:23 AM

A conversão do formato de exibição para o formato original é um pouco mais trabalhoso. Geralmente você usaria os métodos Parse() e TryParse() do tipo Decimal para fazer este serviço mas eles não podem tratar strings que incluem símbolos de moedas.

Função Format - Retorna uma string formatada de acordo com as instruções contidas na expressão String. Sintaxe:

Public Shared Function Format( ByVal Expression As Object, Optional ByVal Style As String = "") As String

A solução é usar uma versão do método sobrecarregado para Parse() e TryParse() que aceitam o valor System.Globalization.NumberStyles. Se você fornecer o valor NumberStyles.Any estará apto remover o símbolo da moeda se ela existir.

Vejamos a seguir um exemplo de um conversor de valor que trata com valores monetários:

<ValueConversion(GetType(Decimal), GetType(String))> _
Public Class PrecoConversor
          Implements IValueConverter

Public Function Convert(ByVal value As Object, ByVal targetType As Type, _
           ByVal parameter As Object, ByVal culture As CultureInfo) As Object _
           Implements IValueConverter.Convert
           Dim preco As Decimal = CDec(value)
           Return preco.ToString("c", culture)
End Function

Public Function ConvertBack(ByVal value As Object, _
                       ByVal targetType As Type, ByVal parameter As Object, _
                       ByVal culture As CultureInfo) As Object _
                       Implements IValueConverter.ConvertBack

             Dim preco As String = value.ToString(culture)
             Dim resultado As Decimal
             If Decimal.TryParse(preco, NumberStyles.Any, culture, resultado) Then
                  Return resultado
             End If
             Return value
End Function
End Class

Para poder usar o conversor você precisa mapear no seu projeto o namespace do seu projeto para um prefixo de namespace XML que você pode usar na linguagem de marcação XAML. Um exemplo que assume o prefixo de namespace local e assume o valor do conversor pode ser escrito assim:

xmlns:local="clr-namespace:DataBinding"

O objeto raiz de um arquivo XAML deve importar pelo menos um namespace para identificar ele mesmo e os seus filhos.

Ao criar um projeto do tipo WPF por padrão são automaticamente definidos os seguintes namespaces no arquivo XAML:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"

Observe que foi utilizado xmlns:x , pois esse é o namespace padrão da linguagem XAML que importa os recursos do namespace System.Windows.Markup e define diretivas especiais para o XAML Compiler e o XAML Parser.

O namespace x já faz o mapeamento dos seguintes namespaces: System.Windows, System.Windows.Automation,System.WindowsSystem.Windows.Controls,System.Windows.Data,System.Windows.Documents,
System.Windows.Forms.Integration,System.Windows.lnk, System.Windows.Input,System.Windows.Media, System.Windows.Navigation, System.Windows.Shapes, System.Windows.Media.Effects,System.Windows.Media.Animation,
System.Windows.Media.Imaging, System.Windows.Media.Media3D.

Este atributo será adicionado na tag <Window> que envolve todo o seu código de marcação XAML.

Feito isso basta você criar uma instância da classe PrecoConversor atribuindo-a para a propriedade Converter da sua vinculação. Para isso você usa a seguinte sintaxe:

<TextBlock Margin="7" Grid.Row="2">Preço:</TextBlock>
<TextBox Margin="5" Grid.Row="2" Grid.Column="1">
<TextBox.Text>
<Binding Path="Preco">
<Binding.Converter>
<local:PriceConverter></local:PrecoConversor>
</Binding.Converter>
</Binding>
</TextBox.Text>
</TextBox>

Em muitos casos o mesmo conversor é usado para múltiplos bindings, neste caso não faz sentido criar uma instância do conversor para cada binding; ao invés disso você pode criar um objeto conversor na coleção Resources conforme o código a seguir:

<Window.Resources>
<local:PrecoConversor x:Key="PrecoConversor"></local:PrecoConversor>
</Window.Resources>

Feito isso você pode apontar para o seu binding usando a referência StaticResource conforme o código abaixo:

<TextBox Margin="5" Grid.Row="2" Grid.Column="1"
Text={Binding Path=Preco, Converter={StaticResource PrecoConversor}">
</TextBox>

E com isso apresentei de forma sucinta como você pode realizar formatação e conversão no WPF.

Veja a segunda parte deste artigo em : WPF - Formatação e conversão de dados - 2

Aguarde mais artigos e dicas sobre WPF.

Eu sei é apenas WPF, mas eu gosto...

Referências:


José Carlos Macoratti