[Tips and Tricks] Como añadir App.xaml en Xamarin.Forms

XAMLIntroducción

Xamarin.Forms es un toolkit que crea una abstracción sobre la interfaz de usuario de Android, iOS y Windows Phone permitiendo desarrollarla una única vez con código C# o Extensible Application Markup Language (XAML).

Cuando creamos una nueva Aplicación Xamarin.Forms:

AppXAML 01

Automáticamente se nos crea una estructura con cuatro proyectos, tres
por cada plataforma nativa y uno con el código común que segun elección
será una PCL o un proyecto Shared. En el código compartido se nos
creará un archivo llamado App.cs:

Estructura de proyecto Xamarin.Forms

Este archivo es el punto de entrada de la App donde se establece la
vista inicial, se realizan inicializaciones y se gestiona el ciclo de
vida compartido de la App. Los desarrolladores .NET con experiencia en
WPF, Windows Phone o Windows Store están acostumbrados a utilizar
también un fichero XAML asociado donde se pueden establecer estilos
comunes a toda la Aplicación además de incluir estilos definidos en
diccionario de recursos. Una forma sencilla y bastante potente para
poder organizar todos los recursos y estilos necesarios.

¿Podemos haer algo similar con Xamarin.Forms?

En este artículo vamos a aprender como reemplazar el archivo App.cs por un archivo App.xaml con su App.xaml.cs asociado.

Creando el archivo App.xaml

En nuestra PCL o proyecto Shared vamos a incluir un nuevo fichero de tipo Forms Xaml Page:

Añadimos App.xaml

Al añadir este archivo veremos la siguiente vista XAML:

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyXamarinFormsApp.App">
  <Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

Con el siguiente código asociado:

public partial class App : ContentPage
{
     public App()
     {
         InitializeComponent();
     }
}

Suprimimos el archivo App.cs y realizamos la siguiente modificación en App.xaml.cs:

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyXamarinFormsApp.App">
 
</Application>

Reemplazamos ContentPage por Application. En el código asociado, la clase derivará también de Application
y de manera opcional añadiremos la sobreescritura de los métodos que
necesitemos (como por ejemplo, los eventos del ciclo de vida).

public partial class App : Application
{
     public App()
     {
 
     }
 
     protected override void OnStart()
     {
         // Handle when your app starts
     }
 
     protected override void OnSleep()
     {
         // Handle when your app sleeps
     }
 
     protected override void OnResume()
     {
         // Handle when your app resumes
     }
}

Si ejecutamos en este punto, todo funcionará exactamente igual a antes del cambio.

Estilos a nivel de Aplicación

Podemos definir recursos a nivel de Aplicación donde crear desde
recursos a estilos más complejos a compartir a lo largo de toda la
aplicación:

<Application.Resources>  
     <ResourceDictionary>
          <Style
               x:Key="AppButtonStyle"
               TargetType="Button">
               <Setter Property="Rotation" Value="25" />
          </Style>
     </ResourceDictionary>
</Application.Resources>

En nuestra vista principal podemos acceder al estilo definido en App.xaml:

<Style x:Key="InheritedAppButtonStyle" TargetType="Button" BasedOn="{StaticResource AppButtonStyle}">
     <Setter Property="BorderColor" Value="Green" />
     <Setter Property="FontSize" Value="Large" />
</Style>

El botón en nuestra vista principal:

<Button
     Text="Herencia de Estilos desde App"
     Style="{StaticResource InheritedAppButtonStyle}"/>

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

Más información

[Material] Mobile Dev Day

El Evento

El pasado Lunes 15 de Junio tenía lugar el evento Mobile Dev Day en las oficinas de Microsoft Ibérica
Un evento con múltiples charlas relacionadas con el desarrollo de Apps
para Windows 10, Apps móviles multiplataforma con Xamarin y detalles
relacionados con el desarrollo de las mismas como la gestión de equipos y
tareas, Builds y Testing.

El Material

Windows 10 ha llegado como la culminación en el viaje hacia la convergencia en el desarrollo entre plataformas Windows. Ahora hablamos de Apps Universales
escritas una única vez con un código común 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. Podemos crear apps que
funcionen en todo tipo de dispositivos como teléfonos, tabletas,
portátiles, dispositivos IoT, Surface Hub e incluso HoloLens.

Comenzamos el evento con
una sesión donde tratamos todas las novedades principales sobre
desarrollo Windows 10: SDK de extensiones, diseño adaptativo, SplitView,
vistas por familias de dispositivos, novedades en XAML, en controles o
en herramientas por ejemplo.

Nuestro
objetivo como desarrolladores es crear aplicaciones útil y atractivas
pero sobretodo perfectamente funcionales. Para poder lograr ese objetivo
es sin duda muy importante la arquitectura aplicada a la App. En la
siguiente sesión vimos el patrón MVVM aplicándolo a una
aplicación Xamarin en cada una de las plataformas paso a paso así como
la cantidad de código que se puede llegar a compartir entre ellas.

Para finalizar el evento, nos centramos en Visual Studio Online
Repasamos conceptos claves en la gestión del ciclo de vida completo de
nuestro proyecto con metodologías ágiles, así como gestionar nuestro
código fuente para terminar viendo como automatizar la compilación o las
pruebas  en nuestros proyectos móviles incluidos desde recientemente
proyectos Xamarin.

En cuanto a las Demos técnicas y Apps realizadas, la tenéis disponibles en GitHub:

Ver GitHub

Quisiera terminar agradeciendo a Microsoft y Bravent por permitir estas actividades y por supuesto a todos los asistentes. Espero que para todos fuese una mañana divertida!

Más información

[Material] Seminario Xamarin en Avante

El Evento

El pasado Martes 09 de Junio tenía lugar Apps Multiplataforma con Xamarin en el Avante.  Un evento con múltiples charlas relacionadas con el desarrollo de Apps móviles multiplataforma con Xamarin.

El Material

Comenzamos el evento con una sesión donde
repasamos el estado actual del mercado y el desarrollo móvil,
introducción a Xamarin como herramienta para crear aplicaciones nativas
multiplataforma desde Visual Studio analizando todas sus bondades y
costes además de ver distintas opciones, Xamarin Classic y
Xamarin.Forms.

Nuestro objetivo como desarrolladores es crear
aplicaciones útil y atractivas pero sobretodo perfectamente
funcionales. Para poder lograr ese objetivo es sin duda muy importante
la arquitectura aplicada a la App. En la siguiente sesión repasaremos el
patrón MVVM aplicándolo a una aplicación Xamarin en cada una de las
plataformas paso a paso así como la cantidad de código que se puede
llegar a compartir entre plataformas.

El ecosistema Xamarin no cesa en las
herramientas de desarrollo. Tenemos a disposición una gran variedad de
servicios destinados a complementar el mismo, analíticas, testing,
análisis de rendimiento, etc. En esta sesión hicimos un repaso por todos
los servicios disponibles realizando demos de cada uno de ellos.

 

En cuanto a las Demos técnicas y Apps realizadas, la tenéis disponibles en GitHub:

Ver GitHub

Quisiera terminar agradeciendo a Avante y Bravent por permitir estas actividades y por supuesto a todos los asistentes. Espero que para todos fuese una mañana divertida y… ¿cuándo repetimos?

Más información

Avante: Seminario Xamarin

[Evento] Mobile Dev Day

El evento

El próximo Lunes 15 de Junio, Microsoft y Bravent han
organizado un evento donde veremos una gran cantidad de aspectos
relacionadas con el desarrollo móvil. Trataremos aspectos como las
novedades a nivel de desarrollo que tenemos con la llegada de Windows
10, como crear y estructurar proyectos móviles multiplataforma
utilizando Xamarin llegando a compartir la mayor cantidad de código
posible tanto con MVVMCross como con Xamarin.Forms además de ver como
gestionar el ciclo de vida de proyectos con metodologías ágiles
automatizando Builds y tests incluidos proyectos móviles
multiplataforma.

¿Te apuntas?

Agenda

  • 10:00h – 10:30h Registro
  • 10:35h – 11:35h Windows 10: Universal Windows Platform.
    Windows 10 ha llegado como la culminación en el viaje hacia la
    convergencia en el desarrollo entre plataformas Windows. Ahora hablamos
    de Apps Universales escritas una única vez con un código común 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. Podemos crear
    apps que funcionen en todo tipo de dispositivos como teléfonos,
    tabletas, portátiles, dispositivos IoT, Surface Hub e incluso HoloLens.
    En esta sesión conoceremos todas las novedades sobre desarrollo Windows
    10.
  • 11:35h – 12:05h Desayuno
  • 12:05h – 13:05h Crear Apps Multiplataforma nativas reutilizando la mayor cantidad de código.
    Aprende a sacar todo el provecho a Xamarin y reutilizar la mayor parte
    del código entre diferentes plataformas, disminuyendo los tiempos de
    desarrollo y facilitando el mantenimiento.
  • 13:05h – 14:05h Novedades en Visual Studio Online.
    Veremos cómo con Visual Studio Online podemos gestionar el ciclo de
    vida completo de nuestro proyecto con metodologías ágiles, así como
    gestionar nuestro código fuente y automatizar la compilación o las
    pruebas incluidas desde recientemente Apps Xamarin.

Fecha

El evento tendrá lugar el próximo Lunes, 15 de Junio de 10:00h a 14:00h. Tendremos tres sesiones de 1 horas de duración cada una.

Lugar

Tendrá lugar en el Microsoft Ibérica situado en el Centro Empresarial La Finca. Tenéis la información exacta del lugar a continuación:

Microsoft Ibérica S.R.L.
Paseo Club Deportivo
Centro Empresarial La Finca – Edificio 1 Pozuelo de Alarcón España

Más información

[Windows 10] La nueva Title Bar

Introducción

Las aplicaciones Windows 10 corren como cualquier otra aplicación de
escritorio en formato ventana. Esta característica añade un nuevo
componente llamado TitleBar que contiene el título de
la Aplicación a la izquierda con los tres conocidos botones para
minimizar, expandir y cerrar a la derecha.

¿Qué opciones presenta?, ¿hasta dónde podemos personalizarlo?

En este artículo vamos a utilizar y personalizar las opciones disponibles de la TitleBar de diferentes formas.

La nueva Title Bar

Crearemos un nuevo proyecto UAP:

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

Nuestro objetivo será trabajar y modificar todas las opciones disponibles en la TitleBar. Veremos a continuación que para trabajar con ella accederemos utilizando ApplicationView.GetForCurrentView().TitleBar por lo que primero aprenderemos como trabajar con ella de forma simple desde code behind para posteriormente crearnos un Behavior y poder modificar sus propiedades directamente desde XAML.

Comenzamos creando nuestra interfaz:

<StackPanel
     HorizontalAlignment="Center"
     VerticalAlignment="Center">
     <Button Content="Use Code Behind"
             Click="CodeBehindClick"
             Margin="5"/>
     <Button Content="Use Behavior"
             Command="{Binding NavigateCommand}"
             Margin="5"/>
</StackPanel>

Muy simple. Contamos con dos botones. El primero de ellos modificará la apariencia de la TitleBar desde un evento en el code behind mientras que el segundo navegará a una nueva vista donde se modificará la apariencia de la TitleBar desde XAML utilizando un Behavior.

NOTA: La TitleBar muestra por defecto un color de fondo gris y los elementos con color negro.

El evento del primer botón:

private void CodeBehindClick(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
 
}  

Tendremos en la ViewModel el comando correspondiente al segundo botón:

private ICommand _navigateCommand;
       
public ICommand NavigateCommand
{
     get { return _navigateCommand = _navigateCommand ?? new DelegateCommand(NavigateCommandExecute); }
}
 
private void NavigateCommandExecute()
{
            
}  

Nos centramos en el evento del primer botón. Podemos modificar el texto
que aparece como título en la TitleBar de forma sencilla:

var applicationView = ApplicationView.GetForCurrentView();
 
// Title

applicationView.Title = "Changed basic TitleBar Information"

Utilizando el método GetForCurrentView de la clase ApplicationView obtenemos la instancia de la ventana correspondiente a la App. Esta instancia cuenta con una nueva propiedad llamada TitleBar que nos da acceso a la misma. Tenemos acceso a las siguientes propiedades básicas para modificar el aspecto:

  • BackgroundColor: Propiedad de tipo Color que define el color de fondo de la barra de título sin incluir el fondo de los botones.
  • ForegroundColor: Propiedad de tipo Color utilizada en el color del texto de título.
  • ButtonBackgroundColor: Propiedad de tipo Color para el fondo de la zona de botones en la parte derecha.
  • ButtonForegroundColor: Propiedad de tipo Color que define el color de los botones.
// Basic TitleBar Properties
var titleBar = applicationView.TitleBar;
titleBar.BackgroundColor = (Color)App.Current.Resources["RedColor"];
titleBar.ForegroundColor = (Color)App.Current.Resources["WhiteColor"];
titleBar.ButtonBackgroundColor = (Color)App.Current.Resources["BlueColor"];

titleBar.ButtonForegroundColor = (Color)App.Current.Resources["WhiteColor"];

Más alla de las propiedades de personalización básica que hemos utilizado, podemos modificar muchas otras como:

// Extra
titleBar.ButtonHoverBackgroundColor = Colors.Yellow;
titleBar.ButtonPressedBackgroundColor = Colors.Orange;

Donde:

  • ButtonHoverBackgroundColor: Propiedad de tipo Color que define el color de fondo del botón al pasar el ratón por encima.
  • ButtonPressedBackgroundColor: Propiedad de tipo Color  para el fondo del botón al ser pulsado.

Tenemos gran cantidad de propiedades para definir la apariencia visual en múltiples estados. Si ejecutamos la App:

Al pasar el ratón sobre cualquier botón de la TitleBar:

Pulsando sobre un botón:

Sencillo, ¿cierto?

Mejorando lo presente, utilizando Behavior

Como hemos podido ver hasta ahora:

  • La TitleBar define la cabecera de nuestra App incluyendo título y botones de gestión (minimizar, maximizar y cerrar).
  • Podemos personalizar el contenido del título.
  • Podemos personalizar totalmente la apariencia.

Sin embargo, en lo visto hasta ahora hacemos uso de code behind.

¿Cómo podemos personalizar la TitleBar directamente desde XAML?

Crearemos un Behavior para ello. Añadiremos la referencia a Extensions SDK:

En nuestro proyecto, dentro de la carpeta Behaviors, crearemos una nueva clase que heredará de IBehavior:

public class TitleBarBehavior : DependencyObject, IBehavior
{
     public DependencyObject AssociatedObject { get; private set; }
 
     public void Attach(DependencyObject associatedObject)
     {
         var titleBar = associatedObject as UIElement;
         if (titleBar == null)
             throw new ArgumentException(
                 "TitleBarBehavior can be attached only to UIElement!");
 
         Window.Current.SetTitleBar(titleBar);
 
         AssociatedObject = associatedObject;
     }
 
     public void Detach()
     {
         AssociatedObject = null;
     }
}

Realizamos la implementación de la interfaz IBehavior asociando el Behavior a un elemento UIElement. A continuación, crearemos propiedades de dependencia para modificar el contenido y aspecto de la TitleBar.

public Color BackgroundColor
{
     get { return (Color)GetValue(BackgroundColorProperty); }
     set { SetValue(BackgroundColorProperty, value); }
}
 
public static readonly DependencyProperty BackgroundColorProperty =
            DependencyProperty.Register("BackgroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnBackgroundColorChanged));
 
private static void OnBackgroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.BackgroundColor = (Color)e.NewValue;
}
 
public string Title
{
     get { return (string)GetValue(TitleProperty); }
     set { SetValue(TitleProperty, value); }
}
 
public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title",
            typeof(string),
            typeof(TitleBarBehavior),
            new PropertyMetadata(string.Empty, OnTitleChanged));
 
private static void OnTitleChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.Title = (string)e.NewValue;
}
 
public Color ForegroundColor
{
     get { return (Color)GetValue(ForegroundColorProperty); }
     set { SetValue(ForegroundColorProperty, value); }
}
 
public static readonly DependencyProperty ForegroundColorProperty =
            DependencyProperty.Register("ForegroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnForegroundColorChanged));
 
private static void OnForegroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ForegroundColor = (Color)e.NewValue;
}
 
public Color ButtonForegroundColor
{
     get { return (Color)GetValue(ButtonForegroundColorProperty); }
     set { SetValue(ButtonForegroundColorProperty, value); }
}
 
public static readonly DependencyProperty ButtonForegroundColorProperty =
            DependencyProperty.Register("ButtonForegroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnButtonForegroundColorChanged));
 
private static void OnButtonForegroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ButtonForegroundColor = (Color)e.NewValue;
}
 
public Color ButtonBackgroundColor
{
     get { return (Color)GetValue(ButtonBackgroundColorProperty); }
     set { SetValue(ButtonBackgroundColorProperty, value); }
}
 
public static readonly DependencyProperty ButtonBackgroundColorProperty =
            DependencyProperty.Register("ButtonBackgroundColor",
            typeof(Color),
            typeof(TitleBarBehavior),
            new PropertyMetadata(false, OnButtonBackgroundColorChanged));
 
private static void OnButtonBackgroundColorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
{
     var applicationView = ApplicationView.GetForCurrentView();
     applicationView.TitleBar.ButtonBackgroundColor = (Color)e.NewValue;
}

Hemos definido propiedades para modificar:

  • Título.
  • Color de fondo de la zona del título.
  • Color del título.
  • Color de fondo de la zona de botones.
  • Color de los botones.

Solo nos queda utilizar el Behavior en nuestra interfaz de usuario. Añadimos los namespaces necesarios:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:TitleBar.Behaviors"

Utilizamos el Behavior en nuestra Vista bindeando las propiedades para modificar el título y colores de gestión de la TitleBar:

<i:Interaction.Behaviors>
     <behaviors:TitleBarBehavior
          Title="Changed from Behavior!"
          BackgroundColor="{StaticResource RedColor}"
          ForegroundColor="{StaticResource WhiteColor}"
          ButtonBackgroundColor="{StaticResource BlueColor}"
          ButtonForegroundColor="{StaticResource WhiteColor}"/>
</i:Interaction.Behaviors>

Navegando a la segunda vista:

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

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

Ver GitHub

En futuros artículos veremos otras posibilidades como inyectar contenido XAML o añadir un botón volver directamente en la TitleBar. Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más información

[Evento] Windows 10 Developer Readiness Powered by MVPs

El evento

Windows 10 ha llegado como la culminación en el viaje hacia la convergencia en el desarrollo entre plataformas Windows. 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. Ante la inmensa cantidad de novedades
disponibles en la nueva plataforma Universal de Windows, nada mejor que
desgranarlas en un webcast.

Windows 10 Developer Readiness - Powered by MVPs

Este evento online es parte de una serie de webcasts que se realizarán a nivel mundial por parte del Programa MVP Award destinado a desarrolladores. El objetivo será aprender acerca de la nueva
Plataforma Universal de Windows además de tener sesiones de preguntas y
respuestas donde poder resolver todas las dudas posibles.

¿Te apuntas?

Fecha

El evento tendrá lugar el próximo Jueves, 11 de Junio de 19:00h a 22:00h. Tendremos una sesión de 3 horas de duración.

Ponentes

En las sucesivas sesiones técnicas rodeadas de la mayor cantidad de código y demos posibles estarán disponibles tres MVPs en el desarrollo de la plataforma Windows, Josué Yeray, Rafa Serna y un servidor.

Más información

[Windows 10] x:Bind, bindings compilados

Introducción

Data binding es un mecanismo mediante el cual
podemos enlazar los elementos de la interfaz de usuario con los objetos
que contienen la información a mostrar. Cuando realizamos data binding,
creamos una dependencia entre el valor de una propiedad llamada target con el valor de otra propiedad llamada source. Donde normalmente, la propiedad target recibirá el valor de la propiedad source.

Es el mecanismo base que nos permite utilizar el patrón MVVM en nuestras Apps móviles logrando:

  • Nos permite dividir el trabajo de manera muy sencilla (diseñadores – desarrolladores)
  • El mantenimiento es más sencillo.
  • Permite realizar Test a nuestro código.
  • Permite una más fácil reutilización de código.

Sin embargo, además de toda la potencia mencionada teníamos ciertas
limitaciones. Los errores de Binding no se producían en tiempo de
compilación de la App además de tener diferentes mejoras relacionadas
con el rendimiento. Limitaciones existentes hasta ahora…

Con la llegada de Windows 1o tenemos la posibilidad de crear bindings compilados en lugar de los bindings clásicos.

¿Cómo se usan?, ¿que aportan?, ¿cúando usarlos?

A todas esas preguntas daremos respuesta en este artículo.

x:Bind

x:Bind es una nueva síntaxis en XAML que cubre un objetivo similar a
Binding. Permite crear un enlace a datos pero con significativas
diferencias. Mientras que con Binding se utiliza reflexión en tiempo de
ejecución para resolver el enlace a datos, con x:Bind se realiza una
validación en tiempo de ejecución ya que son fuertemente tipados y compilados. Además, ofrece potentes mejoras en el rendimiento.

Crearemos un nuevo proyecto UAP:

Nueva App UAP

Nuestro objetivo en este primer ejemplo será crear 1600 Borders
bindeados a colores utilizando Bindings clásicos y Bindings compilados.
De esta forma podremos realizar una interesante comparativa en los
tiempos necesarios por cada forma para realizar el enlace a datos así
como otros detalles interesantes como el consumo de memoria, etc.

Comenzamos creando un diccionario de recursos donde definiremos los distintos colores:

<SolidColorBrush x:Key="BackgroundA" Color="Red" />
<SolidColorBrush x:Key="BackgroundB" Color="Blue" />
<SolidColorBrush x:Key="BackgroundC" Color="Green" />
<SolidColorBrush x:Key="BackgroundD" Color="Yellow" />

A continuación crearemos dos vistas nuevas. En una de ellas crearemos cientos de Borders utilizando enlace de datos clásico:

<Border Height="30" Width="30" Background="{Binding BackgroundA}" />
<Border Height="30" Width="30" Background="{Binding BackgroundB}" />
<Border Height="30" Width="30" Background="{Binding BackgroundC}" />
<Border Height="30" Width="30" Background="{Binding BackgroundD}" />

Mientras que en la otra utilizaremos x:Bind:

<Border Height="30" Width="30" Background="{x:Bind BackgroundA}" />
<Border Height="30" Width="30" Background="{x:Bind BackgroundB}" />
<Border Height="30" Width="30" Background="{x:Bind BackgroundC}" />
<Border Height="30" Width="30" Background="{x:Bind BackgroundD}" />

Para utilizar bindings compilados reemplazaremos {Binding} por {x:Bind}.
Los bindings compilados están fuertemente tipados por lo que es
necesario indicar el tipo del contexto siendo por defecto la página o el
control personal en si.

NOTA: El modo de binding utilizado por defecto en bindings compilados es OneTime.

En la vista principal tendremos un par de botones que nos permitan
instanciar y medir el tiempo necesario para ello en cada caso:

var date = DateTime.Now;
var binding = new XBind();
string diff = string.Empty;
binding.Loaded += (s, args) =>
{
     diff = (DateTime.Now - date).ToString();
     Diff.Text = diff;
};
 
Content.Children.Add(binding);

Si ejecutamos la App y pulsamos el botón “Binding”:

Bindings clásicos

Si utilizamos x:Bind:

x:Bind

Si comparamos los tiempos vemos que… se reduce a practicamente la mitad!

Además, analizando consumo de memoria y CPU vemos la siguiente comparativa.

Uso de CPU utilizando enlace a datos clásico:

Uso de CPU en Bindings clásicos

Uso de CPU utilizando bindings compilados:

Uso de CPU en binding compilado

También se reduce el consumo de memoria en comparación con Bindings clásicos:

Comparativa de consumo de memoria entre Bindings

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

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

Ver GitHub

Utilizando x:Bind

Vista las visibles mejoras a nivel de rendimiento, vamos a crear una App “normal” donde veamos su uso.

Crearemos un nuevo proyecto UAP:

Nueva App UAP

Nueva App UAP

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

En esta ocasión, nuestro objetivo sera crear un listado de casas
donde utilizaremos x:Bind en la plantilla que representará cada elemento
de la lista.

Comenzamos creando la entidad casa dentro de la carpeta Models:

public class House
{
     public string Place { get; set; }
     public string Price { get; set; }
     public string Photo { get; set; }
}

Nuestra interfaz sera muy simple en esta ocasión contando con un sencillo ListView:

<ListView
     ItemsSource="{Binding Houses}" />

El control tiene la fuente de datos enlazada a una propiedad de la ViewModel:

private ObservableCollection<House> _houses;
 
public ObservableCollection<House> Houses
{
     get
     {
          if (_houses == null)
               LoadHouses();
 
          return _houses;
     }
}

Cargaremos el listado de casas con un método creando datos falsos en local de manera aleatoria:

private void LoadHouses()
{
     _houses = new ObservableCollection<House>();
     Random random = new Random();
     for (int i = 0; i < 100; i++)
     {
          _houses.Add(new House
          {
               Place = Places[random.Next(0, Places.Count)],
               Photo = string.Format("ms-appx:///Assets/{0}.png", random.Next(1, 4)),
               Price = string.Format("${0}", random.Next(10000, 100000).ToString())
          });
     }
}

Y llegamos a la parte más importante, la definición del template de cada casa:

<DataTemplate x:Key="HouseTemplate" x:DataType="model:House">
     <Grid Width="200"
           Height="80">
          <Grid.ColumnDefinitions>
               <ColumnDefinition Width="75" />
               <ColumnDefinition Width="*" />
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
               <RowDefinition Height="Auto" />
               <RowDefinition Height="Auto" />
           </Grid.RowDefinitions>
           <Image Grid.RowSpan="2"
              Source="{x:Bind Photo}"
              MaxWidth="70"
              MaxHeight="70" />
           <TextBlock Text="{x:Bind Place}"    
                  Grid.Column="1"
                  FontSize="18"/>
           <TextBlock Text="{x:Bind Price}"  
                  Grid.Column="1"  
                  Grid.Row="1"
                  FontSize="12" />
     </Grid>
</DataTemplate>

Utilizamos x:Bind para enlazar cada elemento visual de la plantilla a
la propiedad deseada. Importante resaltar además de compilados, son
fuertemente tipados. Es obligatorio para no tener errores de compilación
indicar el tipo de los datos a los que accedemos por enlace a datos.
Esto lo realizamos utilizando x:DataType. En nuestro ejemplo, la entidad House.

Nuestro ListView quedara:

<ListView
     ItemsSource="{Binding Houses}"
     ItemTemplate="{StaticResource HouseTemplate}" />

Ejecutando la App:

DataTemplate utilizando x:Bind

 

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

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

Ver GitHub

¿Cuándo utilizar Bindings compilados?

Lo visto hasta ahora nos indica que:

  • Tenemos la posibilidad de tener bindings compilados obteniendo errores en tiempo de compilación.
  • Son fuertemente tipados por lo que debemos indicar el tipo de la información.
  • Obtenemos mejoras en el rendimiento tanto en consumo de CPU como de memoria.

Por lo tanto, ¿lo usamos siempre?

La respuesta corta es no. Entrando en profundidad:

  • Los bindings compilados, en ocasiones,  tienen un comportamiento
    diferente al de los bindings clásicos existiendo situaciones no válidas
    para los primeros.
  • Los bindings compilados como indicamos al nombrarlos se compilan
    permitiéndonos obtener errores en tiempo de compilación pero tambien nos
    aporta limitaciones. No podemos crear bindings compilados dinámicamente
    (añadir o quitar bindings en runtime).
  • Con los bindings clásicos podemos crear un mismo template para
    entidades diferentes siempre y cuando el nombre de las propiedades
    coincida. Con los bindings compilados como hemos visto, estan
    fuertemente tipados y no podemos realizar lo mismo.

Por lo tanto, en nuestros desarrollos entran en juego los bindings
compilados pero no sustituyen en abosluto a los bindings clásicos.
Dependiendo de la situación utilizaremos unos u otros en consecuencia.

Más información

[Windows 10] HTTP Live Streaming

Introducción

En el desarrollo de nuestras Apps hay ciertos contenidos que los
usuarios aprecian especialmente. Entre el contenido destacado contamos
con el multimedia.

HTTP Live Streaming o HLS es un protocolo de
streaming de contenido multimedia que consiste en segmentar en
diferentes archivos pequeños, cada uno de ellos en diferentes tamaños y
calidades para permitir difundir el contenido con una tasa adaptativa
dependiendo de la calidad de la conexión.

HTTP Live Streaming

Hasta ahora podíamos implementar HLS en nuestras Apps utilizando componentes de terceros como por ejemplo Windows Phone Streaming Media o Player Framework.

Con la llegada de Windows 10 contamos con lo necesario para trabajar con contenido multimedia adaptativo gracias a la clase AdaptiveMediaSource.

Crearemos un nuevo proyecto UAP:

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

Nuestro objetivo en este ejemplo será analizar todo lo necesario para
realizar streaming adaptativo de contenido multimedia utilizando las
nuevas APIs disponibles en Windows 10.

Comenzamos diseñando nuestra interfaz. El reproductor será un control de tipo MediaElement:

<MediaElement />

Control que soporta reproducción de audio y video ante múltiples
formatos. Añadiremos también un botón para lanzar la reproducción:

<Button
     Grid.Row="1"
     HorizontalAlignment="Center"
     Content="Play"/>

El resultado:

Al pulsar el botón lanzaremos un comando en la ViewModel:

private ICommand _playCommand;
 
public ICommand PlayCommand
{
     get { return _playCommand = _playCommand ?? new DelegateCommandAsync(PlayCommandExecute); }
}
 
private async Task PlayCommandExecute()
{
 
}

Quedando la definición del botón de la siguiente forma:

<Button
     Grid.Row="1"
     HorizontalAlignment="Center"
     Content="Play"
     Command="{Binding PlayCommand}"/>

El comando se encargará de acceder a contenido multimedia adapatativo:

var hlsUri = new Uri(HlsUrl);
var hlsSource = await AdaptiveMediaSource.CreateFromUriAsync(hlsUri);

La clase AdaptiveMediaSource nos permite trabajar con una fuente de streaming adaptativo. Utilizamos CreateFromUriAsync, método asíncrono que nos permite crear una instancia de AdaptiveMediaSource desde una Uri, es decir, trabajando directamente con una Url.

NOTA: Tenemos la posibilidad de obtener la
instancia de AdaptiveMediaSource trabajando con Streams utilizando el
método CreateFromStreamAsync.

El resultado obtenido es una instancia de la clase AdaptiveMediaSourceCreationResult que contiene información imprescindible relacionada con el estado, conexión y contenido de la fuente de streaming adaptativo:

  • HttpResponseMessage:
    Contiene la respuesta de la petición Http realizada para acceder al
    contenido multimedia. Útil para obtener información sobretodo en caso de
    errores.
  • MediaSource: Instancia de la clase AdaptiveMediaSource  que representa el contenido multimedia.
  • Status: Valor contemplado en enumeración que nos indica el estado de la creación de  MediaSource.

Crearemos una propiedad pública para enlazar contenido obtenido:

private AdaptiveMediaSource _mediaSource;  
 
public AdaptiveMediaSource MediaSource
{
     get { return _mediaSource; }
     set
     {
          _mediaSource = value;
          RaisePropertyChanged();
     }
}

Siempre antes, utilizaremos la propiedad Status para verificar que todo ha ido sin problemas:

if (hlsSource.Status == AdaptiveMediaSourceCreationStatus.Success)
{
     MediaSource = hlsSource.MediaSource;
}

Llegados a este punto, solo tenemos que asignar el contenido obtenido
de la fuente de streaming multimedia adapatativo a nuestro control MediaElement.

Creando un Behavior

A pesar de tener una propiedad Source, la asignación de AdaptiveMediaSource al MediaElement se realiza utilizando el método SetMediaStreamSource del MediaElement, ¿cómo podemos enlazarlo directamente?

Crearemos un Behavior para ello. Añadiremos la referencia a Extensions SDK:

En nuestro proyecto, dentro de la carpeta Behaviors, crearemos una nueva clase que heredará de IBehavior:

public class MediaStreamSourceBehavior : DependencyObject, IBehavior
{
     public void Attach(DependencyObject associatedObject)
     {
         var control = associatedObject as MediaElement;
         if (control == null)
             throw new ArgumentException(
                 "MediaStreamSourceBehavior can be attached only to MediaElement.");
 
         AssociatedObject = associatedObject;
     }
 
     public void Detach()
     {
         AssociatedObject = null;
     }
}

Realizamos la implementación de la interfaz IBehavior asociando el Behavior al elemento MediaElement. A continuación, crearemos una nueva propiedad de dependencia de tipo AdaptiveMediaSource a la que bindearemos la propiedad MediaSource que creamos previamente en nuestra ViewModel:

public AdaptiveMediaSource Media
{
     get { return (AdaptiveMediaSource)GetValue(MediaProperty); }
     set { SetValue(MediaProperty, value); }
}
 
public static readonly DependencyProperty MediaProperty =
            DependencyProperty.Register("Media",
            typeof(AdaptiveMediaSource),
            typeof(MediaStreamSourceBehavior),
            new PropertyMetadata(null, OnMediaChanged));
 
private static void OnMediaChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
     var behavior = sender as MediaStreamSourceBehavior;
     if (behavior.AssociatedObject == null || e.NewValue == null) return;
 
     var mediaElement = behavior.AssociatedObject as MediaElement;
     if (mediaElement != null)
          mediaElement.SetMediaStreamSource((AdaptiveMediaSource)e.NewValue);
}

Al asignar el valor de la propiedad de depencia creada, utilizaremos el método SetMediaStreamSource del control MediaElement para asignar la fuente.

Solo nos queda utilizar el Behavior en nuestra interfaz de usuario. Añadimos los namespaces necesarios:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:HlsPlayer.Behaviors"

Utilizamos el Behavior con nuestro control MediaElement bindeando la fuente de streaming:

<MediaElement
     AutoPlay="True">
     <i:Interaction.Behaviors>
           <behaviors:MediaStreamSourceBehavior
                Media="{Binding MediaSource}"/>
     </i:Interaction.Behaviors>
</MediaElement>

Al ejecutar la Aplicación y pulsar el botón Play:

Comienza la reproducción del streaming adaptativo de contenido multimedia.

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.

Más información

[Windows 10] Nuevas herramientas, Visual Tree Inspector

Introducción

Cada vez que nos llega a los desarrolladores un nuevo SDK, es un
momento especial con una mezcla de altísima curiosidad y ganas de probar
novedades. Entre las novedades principales siempre hay nuevas APIs,
controles y otros elementos para poder realizar Apps que antes no eran
posibles. Sin embargo, entre el conjunto de novedades siempre suelen
venir nuevas herramientas que facilitan ciertas tareas: obtener más
analíticas, mejores medidores de rendimiento, más opciones en
emuladores, etc.

Desde versiones anteriores de Visual Studio, una de las herramientas más demandadas son herramientas de depuración de UI XAML.

Nuevas herramientas

Con Visual Studio 2015 nos llegan nuevas herramientas entre las que
se incluyen herramientas que permiten inspeccionar el árbol de elementos
XAML asi como modificar todas las propiedades de cualquier elemento.
Esta nueva herramienta se llama Visual Tree Inspector.

Visual Tree Inspector

El Árbol visual dinámico es la primera de dos piezas fundamentales para depurar UI XAML.

Esta herramienta nos permite ver el árbol de controles de la App en
ejecución indicando el número de elementos hijos de cada elemento ideal
para entender la estructura visual de una vista compleja y entender
problemas de rendimiento. Además, haciendo sobre un elemento podemos ver
el archivo XAML donde esta definido quedando marcado.

Conociendo la estructura de la vista es fácil navegar por los
elementos del arbol. Son embargo, ¿que ocurre si la vista es compleja y
no conocemos la estructura?

La herramienta incluye una opción para poder seleccionar elementos visuales de forma muy sencilla con un simple clic de ratón.

Seleccionando la primera opción en la herramienta habilitaremos la selección de elementos de la App en ejecución.

Una vez habilitado, podemos seleccionar elementos en la App en
ejecución quedando marcadas también en el árbol de controles y mostrando
el código XAML de la definición.

El elemento seleccionado queda bordeado de rojo. También tenemos la
opción de ver adorners de diseño de la App en tiempo de ejecución.
Podemos activar esta opción con el segundo botón del conjunto de botones
disponible en la herramienta.

Veremos distintas marcas de diseño del elemento seleccionando
dándonos información relacionada con la posición y tamaño del elemento.

Live Property Explorer

La segunda pieza relacionada con las herramientas de depuración de UI XAML es el explorador de propiedades dinámico.

Esta herramienta nos permite ver todas las propiedades del elemento
seleccionado, incluso aquellas sobreescritas. Podemos ver si las
propiedades estan establecidas con valores directos, accediendo a
recursos, etc. Además, y la parte más interesante, permite cambiar los
valores de la App en ejecución directamente viendo los cambios de manera
inmediata.

Más información

Resumen y material de la Windows 10 Game Jam en Sevilla

El evento

Windows 10 ha llegado como la culminación en el viaje hacia la convergencia en el desarrollo entre plataformas Windows. 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. Con las herramientas de desarrollo de
Windows 10 disponibles, había una oportunidad excelente para crear un
nuevo Hackathon, ¿verdad?

Este pasado fin de semana (los días 15, 16 y 17 de Abril) se ha
celebrado un Hackathon de desarrollo de Apps y Juegos para Windows 10 en
Sevilla.

Windows 10 Game Jam

El lugar

El evento tenía lugar en el Cloud Pointing de
Sevilla situado en el Parque Empresarial Nuevo Torneo. La sala en la que
nos situabamos estaba bastante bien equipada con proyectores, buena
disposición de mesas, aire acondicionado, etc. Además la zona era de
fácil acceso y con bastante aparcamiento.

Clouding Point

Ganadores

Los ganadores del Hackathon en esta ocasión han sido juegos en cada categoría:

  • Categoría Profesional. UNepic. Juego 2D de rol con sistema de inventario, combates, gestión de nivel y muchos otros detalles con una historia muy divertida.
UNepic

NOTA: Juego inspirado en UNepic, muy recomendado juego de aventuras y rol creado por el desarrollador español Francisco Téllez de Meneses.

Podéis verlo en movimiento en el siguiente video:

  • Categoría Estudiantes. Hungry Birds. Juego 2D de
    habilidad. Con distintos niveles consiste en recopilar toda la fruta del
    escenario sin morir en el intento para poder pasar al siguiente nivel.
Hungry Birds

El juego en movimiento:

Resaltar que todos los juegos fueron desarrollados con los Quick Starter de Wave Engine.

El material

Tuve el placer de participar en varias sesiones técnicas sobre
desarrollo de Apps Windows 10. Comenzamos viendo las posibilidades del
control RelativePanel, nuevo control de layout que permite posicionar a
los elementos de forma relativa con respecto al panel y ellos mismos
facilitando además la adaptación de los elementos de la interfaz ante
cambios de orientación o tamaño de pantalla. Además, vimos los Adaptive
Triggers utilizados en XAML para detectar condiciones de entorno como
distintos tamaños de pantalla permitiéndonos aplicar distintos estados
visuales para adaptar la interfaz a cada dispositivo.

Tuvimos otra sesión en la que vimos las  principales novedades en
XAML, mejoras en rendimiento, nuevas herramientas, nuevas APIs de
perspectiva 3D, etc.

Por último, alzamos la vista hacia novedades próximas como los nuevos
Bridges que permiten crear Apps Windows 10 desde código Android o iOS,
viendo como será el proceso, que se puede y que no hacer entre otras
muchas cuestiones.

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

Ver GitHub

Llegados a este punto solo me queda agradecer a mi compañero Josué Yeray
por su ayuda durante todo el fin de semana junto a intrépidos MSPs
(Antoni Cobos y Juan Luis Ruiz) que nos acompañaron todos los días, a los chicos de
Wave Engine por su fantástico taller y ayuda continua, a Microsoft por toda la ayuda, al Clouding Point por las instalaciones, a OnCampus por su colaboración y por supuesto a todos los asistentes por sus ganas y entrega durante todo el fin de semana.

¿Cúando repetimos?

Más información