[Windows 10] Control RelativePanel

Ordenando los elementos de la interfaz

Tenemos una gran diversidad de elementos visuales que nos permiten
definir la interfaz de usuario de nuestras Apps. Entre las opciones
disponibles tenemos un grupo especial destinado a organizar otros
elementos, los paneles.

Hasta ahora contábamos con el siguiente listado de paneles XAML en Windows y Windows Phone:

  • Grid: Nos permite crear filas y columnas para organizar los elementos visuales.
  • StackPanel:
    En inglés la palabra “stack” significa apilar o amontonar. Este control
    nos apila los elementos visuales que contiene verticalmente u
    horizontalmente.
  • Canvas: Podemos posicionar los elementos mediante coordenadas X-Y. Utilizamos posiciones absolutas.
  • ScrollViewer: Permite contener elementos más alla de los límites de la pantalla acceciendo a los mismos realizando scroll.
  • Border: Permite dibujar un borde alrededor de otro elemento visual.
  • ViewBox: Permite reescalar el contenido para rellenar el espacio disponible.
  • WrapGrid: Posiciona los elementos hijos secuencialmente de izquierda a derecha y de arriba a abajo.

Adaptando la interfaz

Adaptar la interfaz de usuario a distintos tamaños, orientaciones y
otros cambios no es algo nuevo. Con la llegada de las Apps Modern UI en
Windows 8.0 debíamos gestionar la vista Narrow. Con las Apps Universales
en Windows 8.1 desarrollábamos Apps con Windows Phone y Windows en
mente. Ante este tipo de situaciones, hasta ahora hemos utilizado
diferentes técnicas. Las más habituales son:

  • Vistas XAML separadas por plataforma.
  • Diseño flexible. Utilizar posiciones y tamaños relativos para permitir escalar facilmente.
  • Utilizar diferentes estados visuales (Visual States) para gestionar vistas en diferentes dispositivos, pantallas e incluso orientaciones.

En este artículo vamos a analizar un nuevo panel llamado Relative Panel. Estamos ante un nuevo Panel
que tiene como principal objetivo permitir crear interfaces con diseños
que se adapten con facilidad a cualquier tipo de tamaño. Posiciona a
los elementos que contiene de manera relativa entre ellos.

El control RelativePanel

Con la llegada del SDK de Windows 10 Preview nos llega el Panel Relative Panel. Permite:

  • Posicionar elementos con respecto al panel con múltiples posiciones.
  • Alinear elementos con respecto a sus “hermanos”. Podemos posicionar
    elementos visuales de manera relativa con respecto a otros elementos
    también con distintas opciones para posicionar segun nuestras
    necesidades.

Posicionando elementos

Para probar las posibilidades del nuevo panel crearemos un nuevo proyecto UAP:

Nuestro objetivo en el ejemplo sera añadir múliples rectángulos que
posicionaremos utilizándo todas las opciones disponibles que nos otorga
RelativePanel.

En nuestra vista principal añadimos el Panel:

<RelativePanel>
</RelativePanel>

Comenzamos añadiendo dos rectángulos de 100 x 200 px posicionándolos con respecto al RelativePanel:

<RelativePanel>
     <Rectangle x:Name="BlueRect"
        Height="100"
        Width="200"
        Fill="Blue" />
     <Rectangle x:Name="RedRect"
        Height="100"
        Width="100"
        Fill="Red"
        RelativePanel.AlignHorizontalCenterWithPanel="True"
        RelativePanel.AlignVerticalCenterWithPanel="True" />
</RelativePanel>

Analizamos el trozo de XAML anterior. Podemos posicionar los
elementos visuales dentro del RelativePanel con una serie de propiedades
adjuntas:

  • RelativePanel.AlignLeftWithPanel: Alineación a la izquierda del Panel.
  • RelativePanel.AlignRightWithPanel: Alineado a la derecha del Panel.
  • RelativePanel.AlignTopWithPanel: Alineado en la parte superior del Panel.
  • RelativePanel.AlignBottomWithPanel: Alineado en la parte inferior del Panel.
  • RelativePanel.CenterInPanelHorizontally: Alineado horizontalmente en el centro del Panel.
  • RelativePanel.CenterInPanelVertically: Alineado verticalmente en el centro del Panel.

Por defecto se aplican las propiedades
AlignLeftWithPanel y AlignTopWithPanel, por ese motivo el rectángulo
azul se posiciona en la parte superior izquierda de la ventana. En
cuanto al cuadrado rojo, lo posicionamos en el centro del panel tanto
horizontalmente como verticalmente.

Además de posicionar elementos con respecto al Panel, podemos posicionar
elementos de manera relativa a otros elementos. En nuestro ejemplo,
vamos a posicionar un nuevo rectángulo con respecto a otro:

<RelativePanel>
     <Rectangle x:Name="BlueRect"
        Height="100"
        Width="200"
        Fill="Blue" />
     <Rectangle x:Name="GreenRect"
        Height="100"
        Width="100"
        Fill="Green"
        RelativePanel.RightOf="BlueRect"
        RelativePanel.AlignVerticalCenterWith="BlueRect" />
     <Rectangle x:Name="RedRect"
        Height="100"
        Width="100"
        Fill="Red"
        RelativePanel.AlignHorizontalCenterWithPanel="True"
        RelativePanel.AlignVerticalCenterWithPanel="True" />
</RelativePanel>

El resultado:

Repasemos el último código añadido. Hemos añadido un nuevo rectángulo
verde que se posiciona a la derecha del rectángulo previo azul. Para
ello, se utilizan las propiedades adjuntas RelativePanel.RightOf y RelativePanel.AlignVerticalCenterWith.
La primera propiedad adjunta posiciona al elemento visual a la derecha
del elemento indicado mientras que la segunda lo alinea de forma
centrada verticalmente.

Tenemos una gran variedad de opciones para posicionar un elemento visual con respecto a otro:

  • RelativePanel.Above: Posiciona encima del elemento visual indicado.
  • RelativePanel.Below: Posiciona debajo del emento visual indicado.
  • RelativePanel.LeftOf: Posiciona a la izquierda del elemento visual indicado.
  • RelativePanel.RightOf: Posiciona a la derecha del elemento visual indicado.

En cuanto a establecer la alineación, de nuevo, contamos con una gran diversidad de opciones:

  • RelativePanel.AlignTopWith: Alineación con respecto a la parte superior del elemento visual indicado.
  • RelativePanel.AlignRightWith: Alineación con respecto a la  derecha del elemento visual indicado.
  • RelativePanel.AlignBottomWith: Alineación con respecto a la parte inferior del elemento visual indicado.
  • RelativePanel.AlignLeftWith: Alineación con respecto a la  izquierda del elemento visual indicado.
  • RelativePanel.AlignHorizontalCenterWith: Alineación central de forma horizontal con respecto elemento visual indicado.
  • RelativePanel.AlignVerticalCenterWith: Alineación central de forma vertical con respecto elemento visual indicado.

Continuamos con otro rectángulo posicionado de forma relativa con
respecto al rectángulo inicial azul. En este caso, vamos a posicionar el
rectángulo debajo y de forma centrada:

<RelativePanel>
     <Rectangle x:Name="BlueRect"
        Height="100"
        Width="200"
        Fill="Blue" />
     <Rectangle x:Name="GreenRect"
        Height="100"
        Width="100"
        Fill="Green"
        RelativePanel.RightOf="BlueRect"
        RelativePanel.AlignVerticalCenterWith="BlueRect" />
     <Rectangle x:Name="YellowRect"
        Height="100"
        Width="100"
        Fill="Yellow"
        RelativePanel.Below="BlueRect"
        RelativePanel.AlignHorizontalCenterWith="BlueRect" />
     <Rectangle x:Name="RedRect"
        Height="100"
        Width="100"
        Fill="Red"
        RelativePanel.AlignHorizontalCenterWithPanel="True"
        RelativePanel.AlignVerticalCenterWithPanel="True" />
</RelativePanel>

El resultado:

Podéis descargar el ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Conclusiones

Este nuevo panel llega con un firme objetivo, permitir posicionar de
forma sencilla permitiendo crear interfaces adaptativas a las distintas
plataformas. El uso de RelativePanel junto a los AdaptiveTriggers (y
junto al nuevo control SplitPanel) formarán una base muy comun en una
gran cantidad de Apps UAP.

Más información

[Windows 10] Disponibles las herramientas de desarrollo de Windows 10 Preview!

Introducción

El pasado 23 de Marzo, Microsoft liberaba dentro del programa de
Windows Insider una Preview de las herramientas de desarrollo de Windows
10.

Gallo-blog-2v2

Prerequisitos

Para poder utilizar las herramientas de desarrollo de Windows 10 Technical Preview es necesario tener instalado:

  • Windows 10 Preview en su versión más reciente.
  • Visual Studio 2015 CTP 6.
  • Herramientas de Windows 10 Technical Preview.

Además son necesarios al menos los siguientes requisitos de hardware:

  • Un procesador que cuente con Second Level Address Translation
    (SLAT). Básicamente todos los procesadores i3/i5/i7 cuentan con ello.
  • 4GB de RAM o superior.

¿Que ocurre si solo dispongo de mi inseparable portátil con un dual core?

Si tras verificar que tu procesador no cuenta con SLAT no desesperes.
Podrás desarrollar aplicaciones para Windows 10  solo que sin poder
ejecutar los emuladores de Windows Phone. Si podrás desplegar Apps en tu
propia equipo de desarrollo o en el simulador de Windows.

NOTA: Puedes verificar si tu procesador cuenta con SLAT y DEP utilizando una herramienta de Microsoft, llamada Coreinfo.

Instalación

Comenzamos entrando con nuestra cuenta en el programa de Windows Insider.

Windows Insider

Windows Insider

NOTA: Si aun no tenéis cuenta, a que esperáis!. Podéis crear una cuenta desde este enlace.

Debemos instalar o actualizar a la última versión de Windows 10 Technical Preview (ahora mismo la 10041) para poder soportar el desarrollo de Apps Universales Windows (UAP).

Buscar actualizaciones

Buscar actualizaciones

NOTA: Si cuentas con Windows 10 Technical Preview comprueba actualizaciones para asegurar que estas en la última versión.

El siguiente paso es instalar Visual Studio 2015 CTP6. Lo podemos instalar desde instalador Web o utilizando la ISO.
Es importante contar con esta versión, si tenéis Visual Studio 2015
CTP5 o anterior debemos desinstalarlo antes de instalar la CTP6.

Visual Studio 2015 CTP6

Visual Studio 2015 CTP6

Por último, procedemos a instalar las herramientas de desarrollo de Windows 10 Technical Preview.

Descarga de las herramientas de desarrollo de Windows 10 Technical Preview

Descarga de las herramientas de desarrollo de Windows 10 Technical Preview

Podemos descargar las herramientas utilizando el instalador Web o utilizando la ISO. Tras la descarga la instalación sera la habitual:

Tool for Windows 10

Tool for Windows 10

Llegado a este punto tenemos todo preparado para comenzar a crear
Apps Windows. Tened en cuenta que es una versión Preview, tendremos
muchas más novedades en el //BUILD. Os recomiendo leer los errores y problemas conocidos con la CTP6 de Visual Studio además de las notas relacionadas con las herramientas de desarrollo de Windows 10 Technical Preview.

Permaneced atentos al blog, en próximos artículos iremos analizando novedades en cuanto a herramientas, controles, APIs, etc.

Más información

[Evento WPSUG] Porqué no has terminado, cuando has terminado tu app

Introducción

Nuestro trabajo como desarrolladores de Apps
móviles no termina al publicar la App en la Store. De hecho, podríamos
decir que ahi comienza un verdadero trabajo de análisis, recopilación de
información y diferentes estrategias de Marketing con el fin de
potenciar a la misma.

El evento

El próximo Jueves 26 de Marzo, a las 19:00 (GMT+1)  tendra lugar un Hangout en el que tendremos el placer de contar con Vanessa Estorach,
con quien veremos diferentes técnicas y estrategias de Marketing en
Apps móviles, destacar la App, optimizar resultados, aumentar
beneficios, etc.

  • 19:00 en España
  • 13:00 en Colombia
  • 12:00 en México Centro
  • 13:30 en Venezuela
  • 15:00 en Chile continental

¿Te apuntas?

Más información

[Xamarin.Forms] Soporte para Apps Windows Runtime!

Introducción

Xamarin.Forms es un toolkit que nos crea una abstracción sobre la interfaz de usuario de Android, iOS y Windows Phone permitiendo desarrollar la interfaz de usuario una única vez con código C# o Extensible Application Markup Language (XAML).
Teníamos esta posibilidad con Apps Android, iOS y Windows Phone. Sin
embargo, en el caso de Windows Phone solo se soportaba Silverlight hasta
la versión 8.0. Con la llegada de la versión 8.1 se incorporaron las
aplicaciones WinRT que no estaban soportadas… hasta ahora!

En el marco de la dotNetConf 2015, Xamarin ha anunciado la disponibilidad de la versión Windows Preview. Se añade soporte a:

  • Apps Windows Store: Proyectos Windows destinados a Tabletas.
  • Apps Windows Phone 8.1: Proyectos WinRT Windows Phone 8.1.

En este artículo vamos a crear una App Xamarin.Forms con soporte a Windows y Windows Phone 8.1.

¿Te apuntas?

Preparando la Solución

El soporte en versión Preview de Windows en Xamarin.Forms se ha añadido incluyendo una nueva librería que podemos obtener vía NuGet.
Por lo tanto, en el proyecto creado podemos mantener el paquete NuGet
de Xamarin.Forms añadido, bastará con añadir otro paquete además de
cambiar los tipos de proyectos soportados en la librería PCL (en caso de
usar PCL en lugar de proyecto Shared).

NOTA: La nueva librería no esta aun incluida en
el paquete de Xamarin.Forms al estar en una versión temprana. En futuras
versiones más estables será incorporada.

Crearemos un nuevo proyecto Xamarin.Forms:

 Añadiendo el proyecto Windows

Vamos a comenzar añadiendo el proyecto de la App Windows Store. Clic derecho sobre la solución, nuevo proyecto:

Dentro de la categoría de proyectos de Aplicaciones de la tienda, seleccionamos una App vacía Windows.

Una vez creada, añadimos la referencia a la PCL:

Continuamos añadiendo una referencia al paquete Xamarin.Forms Windows
utilizando NuGet. Para ello, hacemos clic derecho sobre las referencias,
Administrar paquetes NuGet…

Buscamos por “Xamarin.Forms Windows” e instalamos la primera opción.

NOTA: Al instalar Xamarin.Forms Windows se nos añade también las librerías necesarias de Xamarin.Forms.

Ahora llega el momento de preparar el proyecto con leves cambios para utilizar la infraestructura de Xamarin.Forms.

Comenzamos añadiendo en el archivo App.xaml.cs la llamada al método Init en el método OnLaunched:

Xamarin.Forms.Forms.Init (e);

Editamos el tipo de la página principal MainPage.xaml:

forms:WindowsPhonePage

Donde el namespace de forms es:

xmlns:forms="using:Xamarin.Forms.Platform.WinRT"

Suprimimos el tipo Page en MainPage.xaml.cs:

public sealed partial class MainPage

Y en el contructor de la página llamamos al método LoadApplication:

LoadApplication(new Xamarin.Forms_Windows.App());

Y casi todo listo. Basta con revisar el archivo de manifiesto para
asegurar tener marcadas las capacidades de Internet y Localización.

Añadiendo el proyecto Windows Phone

Añadimos el proyecto Windows Phone 8.1:

Al igual que en el caso de Windows añadimos la referencia a la PLC y vía NuGet a Xamarin.Forms Windows.

Al igual que en el proyecto Windows, añadimos en el archivo App.xaml.cs la llamada al método Init en el método OnLaunched:

Xamarin.Forms.Forms.Init (e);

Editamos el tipo de la página principal MainPage.xaml:

forms:WindowsPhonePage

Donde el namespace de forms es:

xmlns:forms="using:Xamarin.Forms.Platform.WinRT"

Suprimimos el tipo Page en MainPage.xaml.cs:

public sealed partial class MainPage

Y en el contructor de la página llamamos al método LoadApplication:

LoadApplication(new Xamarin.Forms_Windows.App());

Todo listo!

Actualizando la PCL (en caso necesario)

Una vez añadidos los dos nuevos proyectos debemos actualizar el
perfil de la PCL. En el proyecto de la misma, hacemos clic derecho y
accedemos a sus propiedades. Veremos algo como:

Pulsamos el botón cambiar y añadimos Windows Phone 8.1:

NOTA: Para poder utilizar los proyectos Windows y
Windows Phone bajo WinRT en Xamarin.Forms se requiere Visual Studio
2013 o superior bajo Windows 8.1.

Comenzando!

Llegados a este punto nuestra solución Xamarin.Forms contará con la siguiente estructura:

Con Windows Preview contamos con dos proyectos más para añadir soporte a Apps Windows y Windows Phone 8.1.

En esta ocasión vamos a retomar un antiguo conocido muy simple
actualizando con el soporte a las nuevas plataformas. Mostraremos un
listado de monos en todas las plataformas utilizando el patrón MVVM.

Comenzamos creando una entidad muy sencilla dentro de la carpeta Models:

public class Monkey
{
     public string Name { get; set; }
     public string Image { get; set; }
     public string Location { get; set; }
     public string Details { get; set; }
}

En nuestra ViewModel definimos una propiedad con  la colección de monos que mostraremos en la interfaz de usuario:

public ObservableCollection<Monkey> Monkeys { get; set; }

Para mantener el enfoque en las nuevas plataformas, reduciremos
complejidad al ejemplo cargando el listado de datos directamente de
datos locales en nuestra ViewModel:

Monkeys = new ObservableCollection<Monkey>
{
     new Monkey
     {
          Name = "Baboon",
          Location = "Africa & Asia",
          Details = "Baboons are African and Arabian Old World monkeys belonging to the genus Papio, part of the subfamily Cercopithecinae.",
     },
     new Monkey
     {
          Name = "Capuchin Monkey",
          Location = "Central & South America",
          Details = "The
capuchin monkeys are New World monkeys of the subfamily Cebinae. Prior
to 2011, the subfamily contained only a single genus, Cebus."
,
     },
     ...
};

Ya con la ViewModel preparada llega el turno de definir la interfaz de usuario. Crearemos una interfaz XAML definida dentro de la carpetas Views en nuestra PCL:

<ListView x:Name="List"
          ItemsSource="{Binding Monkeys}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell Height="50">
          <Grid Padding="5">
            <Grid.RowDefinitions>
              <RowDefinition Height="15" />
              <RowDefinition Height="15" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>            
              <ColumnDefinition Width="50"/>
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>     
            <Image
              Grid.Row="0"
              Grid.RowSpan="2"
              Grid.Column="0"
              Source="{Binding Image}"
              Aspect="AspectFill" />
            <Label
              Grid.Row="0"
              Grid.Column="1"
              Text="{Binding Name}"
              LineBreakMode="TailTruncation" />
            <Label
              Grid.Row="1"
              Grid.Column="1"
              Text="{Binding Location}"
              TextColor="Gray"
              LineBreakMode="TailTruncation" />
          </Grid>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Nuestra App esta lista para funcionar en tabletas Windows además de contar con versión Windows Phone 8.1:

NOTA: En la imagen anterior no aparecen pero seguimos por supuesto contando con App para Windows Phone 8.0 Silverlight e iOS.

Podéis descargar el sencillo ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Conclusiones

Estamos ante una versión Preview y tenemos aun varias limitaciones:

  • No contamos aun con soporte a Mapas.
  • Nos falta el control GridView. En el caso de Apps Windows Store sin duda un control a echar de menos.
  • Algunos controles no se comportan exactamente igual y otros no tienen disponible todas las características.

A pesar de todo, esta versión Preview nos añade soporte para Apps
WinRT en tabletas Windows y en teléfonos Windows Phone 8.1 que era una
de las peticiones quizás más comunes. Es un gran paso adelante y no me
cabe ninguna duda que en los próximos meses (¿alguien dijo //BUILD?) tendremos nuevas versiones añadiendo características.

Más información

[Xamarin.Foms] Pull To Refresh

Novedades de Xamarin.Forms 1.4

La semana pasada Xamarin liberó la versión 1.4.0 de Xamarin.Forms. Una nueva versión con la celeridad a la que nos tienen acostumbrados y cargada de novedades interesantes:

  • Novedades en el ScrollView tanto a nivel de
    propiedades como de evnetos destinados a determinar cuando se realiza
    scroll, mover el scroll a una posición concreta, etc.
  • Novedades en el ListView con nuevas opciones como Header y Footer además de incluir la opció de gestionar Pull To Refresh.
  • Nuevos eventos añadidos a la clase Forms.Application para gestionar la navegación con modales.
  • Corrección de Bugs.

Pull To Refresh

El comportamiento “Pull To Refresh” es un gesto sencillo que permite generalmente refrescar
la información mostrada con un sencillo gesto. Inicialmente introducido
en Tweetie, cliente Twitter de iPhone, gracias a la facilidad de uso la
implementación del comportamiento se ha extendido en cientos de Apps.
De forma habitual consiste en un gesto de deslizamiento desde la parte
inferior hacia abajo, en ese momento se muestra feedback al usuario
indicando que se refrescará la información, de modo que, al levantar el
dedo se produce el refresco.

A pesar de todo, existen ciertas variantes en Apps conocidas en múltiples plataformas.

Pull To Refresh incluido en Xamarin.Forms 1.4.0

En Xamarin Classic y en Xamarin.Forms ya teníamos disponibles algunas
implementaciones para utilizar con todas las plataformas y por supuesto
también podíamos crearnos nuestra propia implementación utilizando
custom renderers. Ahora nos llega una implementación bastante completa y
sencilla directamente en las APIs de Xamarin.Forms:

public event EventHandler Refreshing;
  
public bool IsPullToRefreshEnabled { get; set; } = false;
public bool IsRefreshing { get; set; } = false;
public ICommand RefreshCommand { get; set; } = null;
  
public void BeginRefresh ();
public void EndRefresh ();

Podemos utilizar la propiedad IsPullToRefreshEnabled para habilitar en el ListView el comportamiento “Pull To Refresh”. Cuando el usuario lanza un Pull To Refresh el comando RefreshCommand. La propiedad IsRefreshing nos indica si se esta produciendo el refresco.

NOTA: Podemos establecer la propiedad IsRefreshing a false para terminar con el estado de refresco.

Contámos tambien con eventos para comenzar y detener el refresco. BeginRefresh y EndRefresh respectivamente.

Para probar las posibilidades crearemos un nuevo proyecto Xamarin.Forms:

Añadimos las carpetas Views y ViewModels en nuestra PCL. Añadimos la ViewModelBase y una implementación de DelegateCommand además de una vista XAML. En nuestra página añadiremos un ListView que será el utilizado para implementar Pull To Refresh:

<ListView>
</ListView>

En nuestra ViewModel necesitaremos una propiedad pública con la
colección de elementos a bindear al ListView. Además utilizaremos una
propiedad boolean para determinar si se está produciendo el refresco de
la información o no:

private ObservableCollection<string> _items;
 
public ObservableCollection<string> Items
{
    get { return _items; }
    set { _items = value; }
}
 
private bool _isBusy;
    
public bool IsBusy  
{
     get { return _isBusy; }
     set
     {
          _isBusy = value;
          RaisePropertyChanged();
     }
}

Continuamos añadiendo el comando que se ejecutará al realizar Pull To Refresh:

private DelegateCommandAsync _loadCommand;
 
public ICommand LoadCommand
{
     get { return _loadCommand ?? (_loadCommand = new DelegateCommandAsync(LoadCommandExecute)); }
}
 
private async Task LoadCommandExecute()
{
     await LoadData();
}

En la ejecución del comando se lanza el método LoadData:

private async Task LoadData()
{
     if (IsBusy)
          return;
 
     IsBusy = true;
 
     await Task.Delay(3000);
 
     for (int i = 0; i < 10; i++)
     {
          Items.Insert(0, _count.ToString());
          _count++;
     }
 
     IsBusy = false;
}

Para simplificar el ejemplo se cargan valores numéricos a la
colección. Se verifica que no se estén cargando datos, y se realiza la
carga de diez nuevos elementos.

NOTA: Se añade un retraso de 3 segundos en el método LoadData para simular el refresco desde cualquier servicio.

Nuestro ListView quedaría:

<ListView
     ItemsSource="{Binding Items}"
     HasUnevenRows="True"
     IsPullToRefreshEnabled="True"
     RefreshCommand="{Binding LoadCommand}"
     IsRefreshing="{Binding IsBusy, Mode=OneWay}">
</ListView>

Cargamos la información de la colección Items, permitiendo el comportamiento Pull To Refresh estableciendo la propiedad IsPullToRefreshEnabled a True, controlando si se esta realizando el refresco con la propiedad IsBusy y ejecutamos la lógica de refresco cargando más información mediante el comando LoadCommand.

Si ejecutamos la App, al arrancar cargará los diez primeros elementos:

Realizamos Pull To Refresh:

Se lanza el comando LoadCommand cargando diez nuevos elementos:

Podéis descargar el sencillo ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más información

[Tips and Tricks] Universal Apps. Evento ItemClick a Comando

El problema

Los controles ListView y GridView son
una pieza angular muy importante en la mayoría de aplicaciones Windows
Store y Windows Phone. En su uso necesitaremos determinar cuando el
usuario selecciona un elemento. Trabajando con el patrón MVVM nos encontramos con un problema. Para determinar el elemento seleccionado tenemos dos opciones:

  1. Utilizar la propiedad SelectedItem. Podemos bindear una propiedad de nuestra ViewModel a la propiedad SelectedItem
    del control. Es una opción válida pero en ciertas situaciones puede no
    ser completa. Por ejemplo, si al establecer la propiedad realizamos una
    navegación, al volver atrás si volvemos a intentar navegar al mismo
    elemento no ocurrira nada. Esto es asi, porque la propiedad SelectedItem esta ya establecida y no cambia. Debemos establecer a nulo la propiedad utilizando los eventos de navegación.
  2. Utilizar el evento ItemClick que nos facilita un argumento de tipo ItemClickEventArgs
    con la información del elemento seleccionado. Forma idónea pero con un
    gran problema, no expone una propiedad Command para bindear y utilizar
    nuestra ViewModel.

¿Qué podemos hacer?

En este artículo crearemos una sencilla clase que exponga una propiedad de dependencia adjunta a utilizar.

ItemClick utilizando un Comando

Añadiremos un GridView con su propiedad ItemsSource bindeada a una propiedad de la ViewModel:

<GridView
     ItemsSource="{Binding Items}"
     SelectionMode="None"
     IsSwipeEnabled="false"
     IsItemClickEnabled="True" />

Deshabilitamos los modos de selección y habilitamos el evento ItemClick. En la ViewModel tendremos definida la propiedad:

private ObservableCollection<string> _items;
 
public ObservableCollection<string> Items
{
     get
     {
          if (_items == null)
             LoadData();
         return _items;
     }
     set { _items = value; }
}
La propiedad la instanciará un método LoadData que rellenará la colección de sencillos datos para poder probar:
private void LoadData()
{
     _items = new ObservableCollection<string>();
     for (int i = 0; i < 100; i++)
     {
          _items.Add((i + 1).ToString());
     }
}
Llega el momento clave. Vamos a crear una clase donde definiremos una propiedad de dependencia adjunta (Attached DependencyProperty) de tipo ICommand:
public static class ItemClickCommandBehavior
{
     public static readonly DependencyProperty ItemClickCommandProperty =
            DependencyProperty.RegisterAttached("ItemClickCommand", typeof(ICommand),
            typeof(ItemClickCommandBehavior), new PropertyMetadata(null, OnItemClickCommandPropertyChanged));
 
     public static void SetItemClickCommand(DependencyObject d, ICommand value)
     {
         d.SetValue(ItemClickCommandProperty, value);
     }
 
     public static ICommand GetItemClickCommand(DependencyObject d)
     {
         return (ICommand)d.GetValue(ItemClickCommandProperty);
     }
 
     private static void OnItemClickCommandPropertyChanged(DependencyObject d,
         DependencyPropertyChangedEventArgs e)
     {
         var control = d as ListViewBase;
         if (control != null)
             control.ItemClick += OnItemClick;
     }
 
     private static void OnItemClick(object sender, ItemClickEventArgs e)
     {
         var control = sender as ListViewBase;
         var itemClickCommand = GetItemClickCommand(control);
 
         if itemClickCommand != null && command.CanExecute(e.ClickedItem))
             itemClickCommand.Execute(e.ClickedItem);
     }
}

Cuando se ejecute el evento ItemClick, se tomará el Comando definido en la propiedad, se le pasará el argumento ClickedItem y se ejecutará.

NOTA: Importante resaltar que en la clase utilizamos ListViewBase, por lo que podremos adjuntar la propiedad tanto en controles GridView como ListView.

Ya podremos adjuntar la propiedad en nuestro GridView. Debemos definir el comando a ejecutar en la ViewModel:

private ICommand _clickCommand;
 
public ICommand ClickCommand
{
     get { return _clickCommand = _clickCommand ?? new DelegateCommandAsync<string>(ClickCommandExecute); }
}
 
private async Task ClickCommandExecute(string parameter)
{
     await _dialogService.ShowAsync(parameter);
}

El comando es sencillo. En el método Execute del mismo
recibimos el objeto que contiene al elemento seleleccionado como
parámetro. En nuestro ejemplo, utilizamos un sencillo servicio de
dialogo para mostrar un mensaje con la información del elemento
seleccionado.

Todo listo!. Solo nos queda añadir la propiedad adjunta. Añadimos en la vista el namespace donde hemos definido nuestra clase ItemClickCommandBehavior:

xmlns:behaviors="using:ItemClickCommandBehavior.Behaviors"

Y en el GridView:

De esta forma, tendremos nuestro GridView:

Al pulsar sobre cualquier elemento, nuestra clase dispará el evento ItemClick donde se tomará el comando adjunto y se ejecutará:

Podéis descargar el sencillo ejemplo realizado a continuación:

También podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más información

[Material] Integración Continua de Apps Xamarin

El evento

El pasado Miércoles 11 de Marzo tenía lugar ALMdeando en el Cloud Pointing
de Microsoft situado en el Parque Empresarial Nuevo Torneo.  Un evento
con múltiples charlas relacionadas con ALM y el Testing en CartujaDotNet, grupo de usuarios .NET de Sevilla.

El material

En mi caso, tuve el placer de poder “arrancar” el evento con una charla sobre Integración Continua de Apps multiplataforma con Xamarin y TeamCity.

Tenéis disponible la presentación utilizada a continuación:

En cuanto a las demo técnica realizada junto a todos los scripts, la tenéis disponible en GitHub:

Ver GitHub

Quisiera terminar agradeciendo a Ibón Landa por acercarse a estas tierras donde sale «la esfera de luz en el cielo» y a Juan María Lao, a Microsoft por la sala y por supuesto a todos los asistentes. Espero que para todos fuese una tarde divertida y… ¿cuándo repetimos?

Más información

[Windows 10] Novedades a nivel de desarrollo presentadas en el MWC15

Un primer vistazo a Apps Universales en Windows 10

Windows 10 ha llegado como la culminación en el viaje hacia la convergencia en el desarrollo entre plataformas Windows.

Gracias a esta convergencia, podemos ejecutar nuestra App en
teléfonos, tabletas, PCs y en la Xbox One. Además, debemos unir los
nuevos dispositivos que se unen a la “familia” como dispositivos IoT
como la Raspberry Pi 2.

Universal Apps

Universal Apps

Ahora hablamos de Apps Universales escritas una
única vez con un código comun tanto para la lógica de negocio como para
la interfaz de usuario. Además, generamos un único paquete que mantendrá una interfaz consistente y familiar para el usuario pero adaptada a cada plataforma.

Novedades

Para constuir Apps Universales bajo un mismo paquete, con el mismo
código pero adaptando la experiencia a cada plataforma se han añadido
una serie de novedades a destacar.

UX Adaptable

El modelo de Apps ha sido mejorado en líneas generales pero además se ha mejorado mucho el ViewStateMananger
para permitir crear vistas que se adapten al dispositivo con facilidad.
Esto nos permitirá crear vistas comunes sin separar en ficheros
diferentes por plataforma en la mayoría de casos. Aunque se permitirá
seguir dividiendo vistas en caso necesario.

VisualStateManager

VisualStateManager

Además los controles en tiempo de ejecución se adaptarán
a las condiciones usadas para interactuar por el usuario. De esta
forma, tendremos controles que cambien tamaño u opciones dependiendo de
si se usa entrada táctil o ratón por ejemplo.

Cortana

La integración de Cortana será mayor permitiendo búsqueda de Apps, lanzar Apps más frecuentes, etc.

Cloud

Seguiremos contando con opciones en Azure potentes y versátiles como
Azure Mobile Services o el Hub de notificaciones además del servicio de
notificaciones Windows (WNS), etc. Con Windows 10 llegan más servicios o
algunos serán mejorados como OneDrive o Cortana.

Entrando en materia

En el Hall 8 del MWC, Microsoft puso a disposición del público una
gran cantidad de Surfaces preparadas para permitir probar y crear Apps
Universales Windows 10 mediante dos Hands on Labs guiados.

Devs creando Apps Universales Windows 10

Devs creando Apps Universales Windows 10

Tras probar a fondo todo lo posible, a nivel de desarrollo me gustaría destacar una serie de novedades bastante suculentas.

RelativePanel

Estamos ante un nuevo Panel que tiene como principal
objetivo permitir crear interfaces con diseños que se adapten con
facilidad a cualquier tipo de tamaño. Posiciona a los elementos que
contiene de manera relativa entre ellos.

Veamos un ejemplo sencillo:

<RelativePanel>
    <TextBlock x:Name="MyTextBlock" Text="TextBlock 1" RelativePanel.AlightHorizontalCenterWithPanel="True" />
    <TextBlock Text="TextBlock 2" RelativePanel.RightOf="{Binding ElementName=MyTextBlock}" />
</RelativePanel>

En el trozo de XAML de la parte superior utilizamos el nuevo Panel
para posicionar dos simples textos. El primero de los textos se situará
de manera central en forma horizontal al Panel. El segundo es mucho más
interesante. Su posición será a la derecha del primer texto.

Tendremos disponible una gran variedad de opciones de alineación que serán las que otorgen un potencial muy alto al Panel.

Opciones de alineación del RelativePanel

Opciones de alineación del RelativePanel

Además, podremos utilizar StateTriggers para modificar la relación entre controles segun ciertas condiciones.

SplitView

Para que nos situemos de entrada, muchos conocéis alternativas visuales similares como “Hamburger menu”. Crea un menu deslizante lateral.

SplitView

SplitView

Es impresionantemente sencillo de utilizar. Cuenta con una propiedad Pane que permite establecer el contenido del panel. Podemos mostrar el panel a izquierda o derecha mediante la propiedad PanePlacement y el ancho utilizando OpenPaneLength.

Veamos un sencillo ejemplo:

<SplitView
    x:Name="SplitView"
        OpenPaneLength="200"
        Background="Red"
        PanePlacement="Left">
        <SplitView.Pane>
            <Grid>
                <TextBlock Text="SplitView Pane" />
            </Grid>
        </SplitView.Pane>
        <Grid>
            <TextBlock Text="Content" />
        </Grid>
</SplitView>

Por último, tenemos la propiedad IsPaneOpen para determinar si el menu esta abierto o cerrado.

StateTriggers

Llegamos a una de las novedades más potentes. Hasta ahora
utilizábamos ya Visual States para gestionar la apariencia de la
interfaz de Apps WinRT.

Con una clara inspiración en los triggers de WPF nos llegan los StateTriggers. Su uso es muy simple, realizar un cambio en un elemento visual cuando se cumpla una condición.

Actualmente tenemos disponible AdaptiveTrigger. Basicamente la condición depende de un ancho y alto mínimo que establecemos con las propiedades MinWindowHeight y MinWindowWidth. Cuando la ventana supera el tamaño, el VisualState se activa.

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="WideState">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="600" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="MainGrid.Margin" Value="15, 50" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

¿Os recuerda un poco a las Media Queries en CSS?. Muchos Devs de los que probaron el SDK en alguno de los Hands On Labs me lo comentaron con frecuencia.

Tenemos otra serie de novedades en emuladores, herramientas, etc. que
comentaremos con calma cuando Microsoft lo muestre con más detalles.

¿Qué es lo próximo?

Podríamos resumirlo con suma facilidad, //BUILD. Lo
mostrado en este MWC es sin duda un gran adelanto que nos abre el
apetito vorazmente dejandonos con ansias de mucho más. Se denota un gran
esfuerzo por mejorar las herramientas
de desarrollo, mejorar la plataforma y sobretodo mejorar las opciones
para utilizar y compartir código entre plataformas.

Nos vemos en la próxima!

Nos vemos en la próxima!

Mientras llega la fecha, os recomiendo apuntaros al programa Insider
si aun no lo hicisteis y en el caso de desarrollo, la mejor
recomendación por ahora es crear Apps Universales 8.1 que serán una gran
base de partida cuando la nueva plataforma este disponible.

En el próximo //BUILD se mostrará más, se darán más detalles, etc.
Asi que, no se vosotros pero…¿a llegado ya el BUILD?…¿y ahora?….¿y
ahora?

Más información

[Evento CartujaDotNet] ALMdeando

El evento

La calidad en el software es algo innegociable. Un buen proceso en el
desarrollo y gestión del proceso es fundamental para conseguir ese
objetivo. Desde CartujaDotNet organizamos un nuevo evento sobre ALM
donde veremos como crear tests unitarios, trucos a la hora de hacer
testing, como probar y hacer integración continua junto a otros temas
relacionados.

¿Te apuntas?

Fecha

El evento tendrá lugar el próximo Miércoles, 11 de Marzo de 19:00h a 21:00h. Las sesiones tendrán una duración de entre 30 minutos y 45 minutos con descanso intermedio de 5 minutos.

Lugar

Tendrá lugar en el Cloud Pointing de Sevilla situado en el Parque Empresarial Nuevo Torneo. Tenéis la información exacta del lugar a continuación:

c Biología, 12, Edificio Vilamar 2, 3ª Planta
Parque Empresarial Nuevo Torneo
41015 Sevilla

Agenda y Ponentes

Utilizando Integración continua con Apps Xamarin (Javier Suárez) (45 minutos)

En
esta sesión Javier Suárez nos hablará de integración continua con Apps
Xamarin. La integración continua es fundamental en el desarrollo de
software, independientemente de la plataforma. Detectar problemas tan
pronto como sea posible es una gran victoria, sobre todo en el mundo
móvil. Veremos cómo ejecutar pruebas como parte del proceso de Build,
que cubren las pruebas unitarias, etc.

Continuous Delivery con Release Management (Ibon Landa) (45 minutos)

En
esta sesión veremos qué papel juega Release Management en el ciclo de
vida de la aplicaciones y como lo podemos utilizar para implementar de
principio a fin un pipeline de release para nuestras aplicaciones.

Después
de una introducción a los conceptos más básicos de Continuous Delivery
intentaremos ver de la forma más práctica posible la funcionalidad que
aporta Release Management.

– Making better tests (Juan María Laó Ramos) (30 minutos)
En
esta sesión Juanma nos contrará algunos trucos y buenas prácticas que
ha aprendido arrastrándose por los barrizales de la programación, más
que nada para evitar tener que poner muchas lavadoras después de llegar a
casa y tener más tiempo para los suyos.

Más información

[Material dotNet Spain Conference] Extendiendo Xamarin.Forms

El evento

El pasado 27 y 28 de Febrero tuvo lugar dotNet Spain Conference.
El mayor evento de .NET cubriendo todo el espectro, desde .NET
MicroFramework a desarrollo de Apps, Cloud, IoT, soluciones ERP, etc.
Con dos días de duración, organizado con Tracks de la siguiente forma:

  • Viernes: ALM/Tools, Web, Cloud, Data, Enterprise, Hands-on-lab patrocinadores.
  • Sábado: Apps, Games, IoT, Coding-4-fun, Talleres de programación para niños, Hands-on-labs patrocinadores.

Repleto de sesiones técnicas de elevado nivel además de talleres, stands, etc.

El evento ha sido un éxito rotundo. Con más de 1100 asistentes,
una organización destacable donde cabe agradecer la selección y
organización de la agenda y salas, Hands On Labs e incluso talleres para
los más peques de la casa. La calidad de las sesiones mezclada con el
gran ambiente general ha dejado en todos un agradable sabor de boca.
Además, el evento denota el gran estado que atraviesa la plataforma
.NET. Creo que queda simplificado en una frase de Ángel Sáenz de Cenzano, director de la división de Plataforma, Desarrollo e Innovación de Microsoft.

“Ejemplo de ello son las Microsoft Tecnhical Communities y los .NET Clubs nacidos en el seno de numerosas universidades españolas, y que juntos organizan alrededor de 800 eventos cada año en España
para compartir conocimientos en torno a la plataforma y colaborar en el
desarrollo de nuevos proyectos con el apoyo directo de Microsoft”

Me gustaría terminar agradeciendo a organizadores, ponentes y
asistentes por hacer el posible el evento. Gracias por permitirnos
aprender, conocer a gente, encontrarnos con viejos conocidos, poder
ayudar, etc. Solo puedo añadir un…

¿Repetimos?

El material

He tenido en placer de poder participar en el evento con una sesión acerca de extender Xamarin.Forms en el Track de desarrollo de Apps móviles:

En esta sesión vimos:

  • Breve repaso a Xamarin.Forms tanto a nivel de concepto como de estado actual.
  • Como acceder a APIs nativas de cada plataforma utilizando DependencyService.
  • Como extender XAML creando nuevas extensiones de marcado.
  • Como extender y crear nuevos controles con Custom Renders.
  • Como crear nuevas páginas.

Podéis ver la presentación utilizada a continuación:

En cuanto a las demos técnicas realizadas, las tenéis todas disponibles en GitHub:

Ver GitHub

Más información