[UWP – How To] Crear formularios de Login y Registro

Con UWP estamos hablando de un proyecto que puede ejecutarse en múltiples plataformas, por lo tanto, siempre es conveniente tener preparados estos formularios.

En este ejemplo, me baso en lo referente a los formularios y la navegación entre ellos. En este caso no se va a conectar a ninguna base de datos. Haremos hard coding de los accesos a modo de captar la idea.

Registro

Creamos la página de registro a la aplicación (normalmente esto llama a un servicio como Windows Live, Gmail u otro para las autenticaciones).

La página Registro.xaml quedaría de la siguiente manera:


<Page
x:Class="UWP_Blog.Registro"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_Blog"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Margin="5" Text="Usuario: " />
<TextBlock Grid.Column="0" Grid.Row="1" Margin="5" Text="Email: " />
<TextBlock Grid.Column="0" Grid.Row="2" Margin="5" Text="Contraseña: " />
<TextBlock Grid.Column="0" Grid.Row="3" Margin="5" Text="Confirmación: " />

<TextBox Grid.Column="1" Grid.Row="0" Margin="5" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="5" />
<TextBox Grid.Column="1" Grid.Row="2" Margin="5" />
<TextBox Grid.Column="1" Grid.Row="3" Margin="5" />

<StackPanel Grid.Column="1" Grid.Row="4" HorizontalAlignment="Stretch" Orientation="Horizontal">
<Button Margin="5" Content="Registrar" Click="Registrar_Click" />
<Button Margin="5" Content="Cancelar" Click="Cancelar_Click" />
</StackPanel>
</Grid>
</Page>

Inicio de sesión

Creamos la página de Inicio de Sesión de la aplicación (normalmente esto también llama a un servicio como Windows Live, Gmail u otro para las autenticaciones).

La página Login.xaml quedaría de la siguiente manera:


<Page
x:Class="UWP_Blog.Login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_Blog"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Margin="5" Text="Usuario: " />
<TextBlock Grid.Column="0" Grid.Row="1" Margin="5" Text="Contraseña: " />

<TextBox Name="txtUsuario" Grid.Column="1" Grid.Row="0" Margin="5" />
<TextBox Name="txtContrasena" Grid.Column="1" Grid.Row="1" Margin="5" />

<StackPanel Grid.Column="1" Grid.Row="2" HorizontalAlignment="Stretch" Orientation="Horizontal">
<Button Margin="5" Content="Iniciar" Click="Login_Click" />
</StackPanel>
</Grid>
</Page>

Página inicial

Esta página se puede visualizar una vez que el usuario ha iniciado sesión exitosamente.

La página MainPage.xaml quedaría de la siguiente manera:


<Page
x:Class="UWP_Blog.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_Blog"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Name="txtIngreso" Margin="10" FontSize="20" />
</Grid>
</Page>

Navegación

Para que la navegación entre páginas funcione debemos incluir esta pequeña línea de código en nuestras páginas creadas:


this.Frame.Navigate(typeof(MainPage));

De esta manera he mostrado una forma de navegar entre páginas en un proyecto UWP, faltaría enlazarlo a un servicio de autenticación para que nuestros formularios se hagan efectivos.

[AX 2012 R3 – How To] Administrar excepciones desde X++

En AX, las excepciones funcionan de igual manera que en cualquier lenguaje de programación. Lo que deseo demostrar aquí es un bloque de excepciones completo desde X++ y otro que también pueda administrar errores que se producen en una librería DLL.

Excepciones en X++

En este caso, el bloque de excepciones se presenta de la siguiente manera:


try
{
//Esto producirá un error de división por cero
resultado = num1 / 0;
}
catch (Exception::Numeric)
{
//Error específico que se captura cuando trabajamos con números
error("Error específico");
}
catch
{
//Si el error no pudo ser atrapado por la excepción anterior, se procesa éste
error("Error general.");
}

Excepciones para .NET

En este caso, el bloque de excepciones atrapa errores de librerías .NET:


System.Exception ex;

try
{
//Se llama a la librería .NET, si da error pasa al catch
objetoNET.metodo();
}
catch (Exception::CLRError)
{
ex= CLRInterop::getLastException();
info(ex.ToString());
}

[How To] Serializador anidado utilizando la clase XmlSerializer

En esta ocasión, nos basaremos en la entrada publicada la semana pasada aquí.

En esta ocasión necesitamos obtener un XML anidado con varios elementos y sus respectivos atributos:


?<?xml version="1.0" encoding="utf-8"?>
<ejemplo>
<padre>
<hijo Atributo1="" otroatributo="soy otro atributo">
<Codigo>0</Codigo>
<Texto />
<Fecha>2017-02-24T14:30:05.2897119-03:00</Fecha>
</hijo>
</padre>
</ejemplo>

Serializar una clase

Aquí recibimos como parámetro un objeto y lo convertimos a XML.

Primeramente, creamos la clase (que se convertirá al formato XML):


using System;
using System.Xml.Serialization;

namespace ConsoleBlog
{
[XmlRoot("ejemplo")]
public class Ejemplo
{
private Padre padre_ = new Padre();

[XmlElement("padre")]
public Padre Padre
{
get
{
return padre_;
}

set
{
padre_ = value;
}
}
}

[XmlType("padre")]
public class Padre
{
private Hijo hijo_ = new Hijo();

[XmlElement("hijo")]
public Hijo Hijo
{
get
{
return hijo_;
}

set
{
hijo_ = value;
}
}
}

[XmlType("hijo")]
public class Hijo
{
private int codigo = 0;
private string nombre = string.Empty;
private DateTime fecha = DateTime.Now;
private string atributo1 = string.Empty;
private string atributo2 = "soy otro atributo";

private string nomeincluyen = ":(";

[XmlElement]
public int Codigo
{
get
{
return codigo;
}

set
{
codigo = value;
}
}

[XmlElement("Texto")]
public string Nombre
{
get
{
return nombre;
}

set
{
nombre = value;
}
}

[XmlElement]
public DateTime Fecha
{
get
{
return fecha;
}

set
{
fecha = value;
}
}

[XmlAttribute]
public string Atributo1
{
get
{
return atributo1;
}

set
{
atributo1 = value;
}
}

[XmlAttribute("otroatributo")]
public string Atributo2
{
get
{
return atributo2;
}

set
{
atributo2 = value;
}
}

[XmlIgnore]
public string Nomeincluyen
{
get
{
return nomeincluyen;
}

set
{
nomeincluyen = value;
}
}
}
}

El método para serializar la clase y convertirlo a XML sería:


public static string SerializarXML()
{
//XML a ser retornado
string resultado = string.Empty;

//Variables para definición de XML
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
XmlSerializer serializer = new XmlSerializer(typeof(Ejemplo));
Ejemplo ejemplo = new Ejemplo();
Encoding encoding = Encoding.GetEncoding("UTF-8");
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = false,
Encoding = encoding
};

//Agregar un espacio de nombres vacío
ns.Add("", "");

//Se utiliza using para que el objeto sea eliminado luego de su uso
using (var stream = new MemoryStream())
{
//Creamos un XML
using (var xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
//Convertimos la clase en XML
serializer.Serialize(xmlWriter, ejemplo, ns);
}
//Asignamos el XML creado a nuestra variable
resultado = encoding.GetString(stream.ToArray());
}

return resultado;
}

Luego realizamos la llamada y retornamos el XML:


static void Main(string[] args)
{
string xml = Program.SerializarXML();

Console.WriteLine(xml);

Console.ReadKey();
}

Para deserializar se utiliza el mismo método utilizado en el artículo anterior.

[AX 2012 R3 – How To] Index versus Index Hint

Debido a este punto he tenido algunas discusiones con mis colegas debido a las diferencias que existen entre estas cláusulas.

Index Hint

Básicamente, Index Hint en AX 2012 ya está en desuso, para describirlo mejor el AX 2012 lo ignora (es decir, no existe para el).

Un ejemplo de Index Hint podrías ser:


select * from InventTable index hint GroupItemIdx;

Para el AX 2012, la consulta la lee de la siguiente manera:


select * from InventTable;

Como vimos el Index Hint ya no se utiliza en AX 2012.

Index

Esta clásula indica que la consulta en cuestión ordenará, por dicho campo, los registros obtenidos


select * from InventTable index GroupItemIdx;

Para el AX 2012, la consulta la lee de la siguiente manera:


select * from InventTable group by ItemGroupId, ItemId;

[How To] Simple serializador utilizando la clase XmlSerializer

En ocasiones es necesario que nuestras clases puedan verse como archivos XML estructurados, lo primero que se nos viene a la cabeza es que necesitamos armar todo un conjunto de reglas para poder ajustar los detalles según sean necesarios.

Vamos a colocar un escenario común de complejidad media. Digamos que tenemos un servicio Web en Java el cual necesita un XML formateado según las especificaciones de éste. El archivo XML que el servicio Web Java necesita es como sigue:


?<?xml version="1.0" encoding="utf-8"?>
<ejemplo Atributo1="" otroatributo="soy otro atributo">
<Codigo>0</Codigo>
<Texto />
<Fecha>2017-02-14T21:25:39.4120419-03:00</Fecha>
</ejemplo>

Entonces lo que debemos hacer es utilizar la clase XmlSerializer, para poder convertir nuestra clase en un archivo XML según la necesidad o bien convertir de XML a un objeto que hayamos creado.

Serializar una clase

Aquí recibimos como parámetro un objeto y lo convertimos a XML.

Primeramente, creamos la clase (que se convertirá al formato XML):


using System;
using System.Xml.Serialization;

namespace ConsoleBlog
{
[XmlRoot("ejemplo")]
public class Ejemplo
{
private int codigo = 0;
private string nombre = string.Empty;
private DateTime fecha = DateTime.Now;
private string atributo1 = string.Empty;
private string atributo2 = "soy otro atributo";

private string nomeincluyen = ":(";

[XmlElement]
public int Codigo
{
get
{
return codigo;
}

set
{
codigo = value;
}
}

[XmlElement("Texto")]
public string Nombre
{
get
{
return nombre;
}

set
{
nombre = value;
}
}

[XmlElement]
public DateTime Fecha
{
get
{
return fecha;
}

set
{
fecha = value;
}
}

[XmlAttribute]
public string Atributo1
{
get
{
return atributo1;
}

set
{
atributo1 = value;
}
}

[XmlAttribute("otroatributo")]
public string Atributo2
{
get
{
return atributo2;
}

set
{
atributo2 = value;
}
}

[XmlIgnore]
public string Nomeincluyen
{
get
{
return nomeincluyen;
}

set
{
nomeincluyen = value;
}
}
}
}

El método para serializar la clase y convertirlo a XML sería:


public static string SerializarXML()
{
//XML a ser retornado
string resultado = string.Empty;

//Variables para definición de XML
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
XmlSerializer serializer = new XmlSerializer(typeof(Ejemplo));
Ejemplo ejemplo = new Ejemplo();
Encoding encoding = Encoding.GetEncoding("UTF-8");
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = false,
Encoding = encoding
};

//Agregar un espacio de nombres vacío
ns.Add("", "");

//Se utiliza using para que el objeto sea eliminado luego de su uso
using (var stream = new MemoryStream())
{
//Creamos un XML
using (var xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
//Convertimos la clase en XML
serializer.Serialize(xmlWriter, ejemplo, ns);
}
//Asignamos el XML creado a nuestra variable
resultado = encoding.GetString(stream.ToArray());
}

return resultado;
}

Luego realizamos la llamada y retornamos el XML:


static void Main(string[] args)
{
string xml = Program.SerializarXML();

Console.WriteLine(xml);

Console.ReadKey();
}

Deserializar un XML

Aquí recibimos como parámetro una cadena de caracteres (string) y lo convertimos a un objeto .NET.
Primeramente, creamos el método (que convertirá el formato XML a un objeto):


public static Ejemplo DeserializarXML(string xml)
{
//Objeto a ser retornado
Ejemplo resultado = null;
//Variables
XmlSerializer serializer = new XmlSerializer(typeof(Ejemplo));
//Lector de XML
using (TextReader reader = new StringReader(xml))
{
try
{
//Convertimos XML a clase
resultado = serializer.Deserialize(reader) as Ejemplo;
}
catch (Exception ex)
{
//Si hay error lo imprimimos
Console.WriteLine(ex.Message);
}
}

return resultado;
}

Luego realizamos la llamada y retornamos el objeto.

[AX 2012 R3 – How To] Importar/exportar proyectos en AOT

En esta entrada intentaré explicar cómo importar/exportar proyectos privados/compartidos en Microsoft Dynamics AX 2012 R3.

Cómo el título indica vamos a exportar (desde AX hacia el sistema de archivos del sistema) un proyecto de prueba. Una vez realizada la exportación, procederemos a importar el mismo en el AOT, demostrando cómo cumplir con el objetivo de esta entrada.

Exportar proyecto

Dentro del proyecto, hacemos clic derecho sobre el proyecto y seleccionamos «Exportar»:
1

Luego seleccionamos la ruta donde vamos a exportar y seleccionamos los elementos a exportar:
2

Una vez terminado, hacemos clic en el botón «Aceptar» y la exportación estará lista en segundos/minutos dependiendo del contenido del mismo.

Importar proyecto

El proceso de importación es más simple aún. Se puede realizarlo desde el AOT haciendo clic en el ícono correspondiente. Marcamos la opción de «obtener objetos de aplicación y etiquetas»:
3

Hacemos clic en «Aceptar» y la importación estaría correcta.

Generalmente, hay elementos que ya existen y el sistema pregunta si deseamos sobreescribir elementos. También, se compila el proyecto importado. Si hay errores debemos corregirlos luego de la importación.

Conclusión

De manera muy sencilla y en pocos pasos logramos realizar las dos tareas con el menor esfuerzo posible. Se debe tener en cuenta que si importamos en una misma capa todos los cambios existentes en dicha capa serán sobreescritos.

[How To] Convertir una aplicación WPF a UWP

En el sitio oficial de MSDN se encuentra una documentación perfecta sobre este tema, así que la intención de esta entrada es tener ordenada dicha información.

¿Cuáles son los pasos para convertir una aplicación WPF a una UWP?

Necesitamos entender de qué se trata este proceso, aquí.

Si lo hacemos mediante el proceso manual (especialmente cuando utilizamos controles tercerizados como Telerik o DevExpress)

¿Cómo se realiza el proceso?

El proceso se realiza de esta manera.

¿Qué es DAC y cómo lo utilizamos?

Básicamente lo descargamos y realizamos los siguientes pasos.

Espero que esta información resulte útil para realizar estos pasos bien útiles para convertir nuestras aplicaciones WPF a UWP, de modo a que funcione en todos nuestros dispositivos Windows.

[AX 2012 R3 – How To] Implementar todos los reportes SSRS

Muchas veces queremos implementar todos los reportes de una vez. Se complica un poco, si no tenemos la herramienta correcta para realizar dicha tarea.

Básicamente se realiza la tarea ejecutando una línea de comandos desde el powershell de Microsoft Dynamics AX.

A modo de introducción podemos decir que existen unas cuantas formas de implementar un reporte en el servidor de informes (SSRS – SQL Server Reporting Services). Aquí trataremos los 3 más utilizados y necesarios.

Visual Studio

Esta es la opción que más utilizo por su facilidad y rapidez. De hecho los reportes se diseñan/desarrollan desde el Visual Studio.
Abrir proyecto de reporte > Clic derecho sobre el proyecto > Implementar (Deploy). 1

Una vez realizada la acción anterior recibiremos el mensaje de buen funcionamiento o el de error si lo hay.
2

AOT

Esta segunda opción permite implementar el reporte desde el AX. Un buen escenario sería al importar un proyecto que ha definido cambios en los reportes, entonces éstos deben ser implementados para que puedan ser reflejados.
AOT > SSRS Reports > Reports > Clic derecho sobre el reporte > Implementar elemento.
3

 Una vez realizada la acción anterior recibiremos el mensaje de buen funcionamiento o el de error si lo hay.
4

Microsoft Dynamics AX Powershell

Desde aquí podemos implementar un sólo reporte o implementar todos los reportes. Para ello debemos ingresar al powershell de Microsoft Dynamics AX. Nos dirigimos a Inicio > Herramientas administrativas > Microsoft Dynamics AX 2012 Management Shell. Allí veremos el powershell de manera similar a la siguiente:
5

Implementación de un reporte específico

Aquí ejecutamos la acción de implementar un reporte (VendAdvanceInvoice, por ejemplo) desde el powershell:

Publish-AXReport -ReportName VendAdvanceInvoice

Implementación de un grupo de reportes

Si deseamos implementar un grupo de reportes (para compras, por ejemplo):

Publish-AXReport -ReportName Purch*

Implementación de todos reportes

Si deseamos implementar todos los reportes existentes dentro del AX, utilizamos el comodín *:

Publish-AXReport -ReportName *

En cualquiera de los tres casos, el resultado será similar al siguiente: 6