Como o intuito é ser um seletor de datas que funciona em diversas plataformas diferentes, o elemento DatePicker do Xamarin Forms acabou por não levar em consideração diversas peculiaridades de cada plataforma. É um dos casos em que generalizar demais acaba por tirar a individualidade, os seletores de data nativos do Android, iOS e das plataformas Windows, funcionam de maneiras diferentes, e não tem nada de errado com isso.
Os problemas:
Caso você nunca tenha utilizado o elemento DatePicker do Xamarin Forms, aqui estão alguns exemplos de porque ele não é a escolha ideal:
- O evento de seleção de data só é disparado caso o usuário tenha de fato escolhido uma data, se for escolhida a data inicial do seletor ele não será disparado.
- Como o evento de escolha de data não é ativado se a data inicial for mantida, o resultado obtido ao inspecionar a propriedade Date do DatePicker neste caso será um objeto new DateTime(), que aponta para a data 01/01/0001, o que na maioria dos casos não irá condizer com a realidade da data inicial.
- Já que o evento de seleção de datas não é confiável podemos atribuir manualmente o valor da data inicial por data binding e usar o evento de perda de foco do seletor, o problema deste caso é que o evento de perda de foco também é disparado quando o usuário cancela a seleção de data, o que torna esta abordagem inviável.
As soluções:
Abaixo apresento três soluções para o problema de inserir um seletor de datas em aplicativo Xamarin Forms, cada um com suas vantagens e desvantagens.
Solução rápida e barata:
A solução mais rápida e barata para apenas incluir um seletor de data é usar um dialog nativo, o que pode ser facilmente feito com o pacote nuget Acr.User.Dialogs (https://github.com/aritchie/userdialogs), que tem implementações para Android, iOS e UWP.
Vantagens:
- Pouco trabalho para implementar;
- Cross-platform;
- Pacote sem custo adicional.
Desvantagens:
- Como a implementação é apenas na forma de um dialog, os controles de exibição do seletor e da data selecionada devem ser construídos separadamente, o que pode aumentar o tempo de desenvolvimento consideravelmente;
- Pouca capacidade de customização dos elementos visuais.
Solução demorada mas sem custo adicional:
Caso queira um seletor de data funcional e com a interface customizável, uma das soluções é implementar o seu próprio. Isso seria um grande desafio em muitos casos, mas o uso das classes DateTime e Calendar do .NET auxilia muito o desenvolvimento. Para permitir uma seleção de diversos meses e/ou anos, recomendo construir a interface com uma CarouselView (https://blog.xamarin.com/flip-through-items-with-xamarin-forms-carouselview/), e para o seu seletor parecer mais uma caixa de diálogo e menos com um modal recomendo o uso do pacote Rg.Plugins.Popup (https://github.com/rotorgames/Rg.Plugins.Popup).
Vantagens:
- Construído pensando nas especificidades de cada projeto;
- Possibilidade muito ampla de customização do layout;
Desvantagens:
- Mesmo com o auxílio das ferramentas citadas, ainda é um trabalho que gasta um tempo considerável;
- Maior possibilidade de bugs, já que a implementação foi feita apenas para o projeto.
Solução rápida e cara:
Existem bibliotecas gráficas pagas que implementam seletores de data e calendários customizados e sem os problemas relacionados a eventos e inicializações, os que considero mais interessantes são:
- Telerik – Calendar: http://www.telerik.com/xamarin-ui/calendar
- Syncfusion – SfCalendar: https://help.syncfusion.com/xamarin/sfcalendar/getting-started
- Syncfusion – SfPicker: https://help.syncfusion.com/xamarin/sfpicker/datepicker
Vantagens:
- Bibliotecas já consolidadas no mercado, com baixa probabilidade de bugs ou de causarem crashes no aplicativo;
- Customizáveis e com visual padrão muito agradável;
- Implementação simples.
Desvantagens:
- Custo adicional no projeto pode inviabilizar esta solução;
- Apesar de serem de simples implementação, é possível que gerem um overhead de aprendizado de uso pelos desenvolvedores.
Referências:
- Acr.UserDialogs: https://github.com/aritchie/userdialogs;
- .NET Calendar: https://msdn.microsoft.com/en-us/library/system.globalization.calendar(v=vs.110).aspx?f=255&MSPPError=-2147217396;
- .NET DateTime: https://msdn.microsoft.com/pt-br/library/system.datetime(v=vs.110).aspx;
- CarouselView: https://blog.xamarin.com/flip-through-items-with-xamarin-forms-carouselview/;
- Rg.Plugins.Popup: https://github.com/rotorgames/Rg.Plugins.Popup;
- Telerik – Calendar: http://www.telerik.com/xamarin-ui/calendar;
- Syncfusion – SfCalendar: https://help.syncfusion.com/xamarin/sfcalendar/getting-started;
- Syncfusion – SfPicker: https://help.syncfusion.com/xamarin/sfpicker/datepicker;