Currency UI in Xamarin.Forms


Normalmente cuando estamos trabajando con nuestro diseñador visualizando o apoyándolo con el flujo de la aplicación u algunos elementos que se requieren desarrollar de manera inmediata, a veces no pensamos en los componentes que tendremos que hacer para que realice lo que requiere el cliente en la interfaz de usuario, y es que si prestamos atención, existen diversos aspectos que podemos hacer para mejorar la experiencia del usuario al personalizar o mejorar controles, los cuales pueden estar en algún formulario y que sean relevantes ante su interacción con nuestra aplicación.

Siguiendo con el patrón de las publicaciones anteriores de mis compañeros con referencias hacia aplicaciones Bancarias, en este artículo veremos cómo generar un control que nos permita convertir el valor numérico de un Entry a un valor monetario.

Comencemos

1- Una vez creado nuestra solución, generemos las carpetas Classes, Converters y ViewModels en nuestro proyecto Portable, en donde agregaremos las clases relacionadas a las necesidades que soportara la aplicación.

2- Partamos por la carpeta Classes, en donde agregaremos una clase denominada: ObservableObject, la cual será la que detecte los cambios de propiedad en nuestro Entry, el código es:

using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace CurrencyUISample.Classes
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

view raw
ObservableObject.cs
hosted with ❤ by GitHub

3- En la carpeta de Converters generaremos la clase que tendrá toda la lógica para hacer la conversión, llamémosle: CurrencyConverter.

CurrencyConverter

Tomemos en cuenta que en lugar de extender nuestros modelos con más y más valores, los Converters nos permiten transformar unos valores a otros directamente desde XAML, ejemplo:

<Label Text=”{Binding Date}” />

using System;
using Xamarin.Forms;
using System.Globalization;
using System.Text.RegularExpressions;
namespace CurrencyUISample.Converters
{
/// <summary>
/// Converter for using in Entry fields for masked input of currency.
/// <b>The binded property must be of type decimal, and must invoke the
/// PropertyChangedEventArgs event whenever the value is changed, so that the desired mask behavior is kept.</b>
/// </summary>
public class CurrencyConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Decimal.Parse(value.ToString()).ToString("C");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string valueFromString = Regex.Replace(value.ToString(), @"\D", "");
if (valueFromString.Length <= 0)
return 0m;
long valueLong;
if (!long.TryParse(valueFromString, out valueLong))
return 0m;
if (valueLong <= 0)
return 0m;
return valueLong / 100m;
}
}
}

view raw
CurrencyConverter.cs
hosted with ❤ by GitHub

4- Continuemos en el sendero de crear clases en las carpetas, en la última (ViewModels), deberemos de crear el ViewModel de la vista MainPage, entonces asignémosle el nombre de: MainPageVM y añadamos lo siguiente:

using Xamarin.Forms;
using System.Windows.Input;
using CurrencyUISample.Classes;
namespace CurrencyUISample.ViewModels
{
public class MainPageVM: ObservableObject
{
private INavigation _navigation;
public ICommand TransferMoneyCommand {get; set;}
public MainPageVM(INavigation navigation)
{
}
private decimal numbertoMoney { get; set; }
public decimal NumbertoMoney
{
get { return numbertoMoney; }
set
{
numbertoMoney = value;
OnPropertyChanged();
}
}
}
}

view raw
MainPageVM.cs
hosted with ❤ by GitHub

5- Agreguemos el Converter en la vista MainPage.xaml.

El Converter es una clase que hereda de la interfaz IValueConverter, se implementa el método Convert y ConvertBack. Para utilizar el converter se debe definir primero como recurso:

<ContentPage.Resources>

<ResourceDictionary>

<util:CurrencyConverter x:Key=”currencyConverter” />

</ResourceDictionary>

</ContentPage.Resources>

Y posteriormente, utilizar la palabra reservada Converter para acceder al mismo:

<Entry x:Name=”NumbertoMoney” Keyboard=”Numeric” Text=”{Binding NumbertoMoney, Converter={StaticResource currencyConverter}}”/>

NOTA: Se suelen utilizar los Converters para transformaciones más complejas.

XAML Completo:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:util="clr-namespace:CurrencyUISample.Converters;assembly=CurrencyUISample"
mc:Ignorable="d" x:Class="CurrencyUISample.MainPage"
BackgroundColor="{StaticResource Bluebull}">
<ContentPage.Resources>
<ResourceDictionary>
<util:CurrencyConverter x:Key="currencyConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Image Source="blue_bull.png" HeightRequest="90" WidthRequest="90"
VerticalOptions="End" HorizontalOptions="End"/>
<StackLayout>
<Frame HasShadow="false"
BackgroundColor="{StaticResource colorBankAmerica}">
<StackLayout Orientation="Horizontal" >
<Image Source="logoBankAmerica.png"
HeightRequest="120"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</Frame>
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="Center"
Orientation="Vertical"
Margin="10,0,10,0">
<Label Text="Quantity to Transfer" TextColor="White"/>
<Entry x:Name="NumbertoMoney" Keyboard="Numeric"
Text="{Binding NumbertoMoney, Converter={StaticResource currencyConverter}}"/>
<Label Text="Concept" TextColor="White"/>
<Editor x:Name="conceptEdt" VerticalOptions="FillAndExpand" Keyboard="Default"
Text="" HeightRequest="50" IsTextPredictionEnabled="true" />
<Label Text="Date" TextColor="White"/>
<DatePicker x:Name="datePck"/>
<BoxView HorizontalOptions="FillAndExpand"
Color="{StaticResource Secondary}"
Visual="Default"
HeightRequest="1"
Margin="0,30"/>
<Button x:Name="transferBtn"
Text="Make a Transfer"
BackgroundColor="White"
CornerRadius="26"
FontSize="18"
Padding="15"
TextColor="{StaticResource Bluebull}"
Margin="30,0,30,30"/>
</StackLayout>
</Grid >
</ContentPage>

view raw
MainPage.xaml
hosted with ❤ by GitHub

6- Por último, en nuestro MainPage.xaml.cs invoquemos al ViewModel antes creado:

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using CurrencyUISample.ViewModels;
namespace CurrencyUISample
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
MainPageVM vm = null;
public MainPage()
{
InitializeComponent();
vm = new MainPageVM(this.Navigation);
this.BindingContext = vm;
}
}
}

view raw
MainPage.xaml.cs
hosted with ❤ by GitHub

Con esto hemos terminado, guardemos, compilemos y probemos.

Resultado

CurrenyUI

Acerca de este articulo

Este es el artículo número 22 de #XamarinUIJuly, que es básicamente una serie de publicaciones de blog donde cada día de Julio un miembro de la comunidad de Xamarin publica un blog sobre Xamarin y las interfaces de usuario. Puedes ver más información aquí:XamarinUIJuly

Descarga el código completo desde mi GitHub.

¡Happy Coding!

 

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s