Xamarin.Forms – Ejecutando código JavaScript desde C#

Si has trabajado anteriormente con Xamarin, tal vez hayas utilizado el control WebView. Dicho control nos sirve para mostrar una página web dentro de nuestra aplicación, tal como el siguiente ejemplo:

Tal vez, una cosa que desconozcas es que se puede invocar una función JavaScript, ¡Desde tu código C#!

Para esto, lo que haremos será crear un archivo tipo .html dentro de nuestro proyecto portable, en una solución tipo Xamarin.Forms:

Dicho archivo, debe tener en sus propiedades, asignada la opción “Embedded Resource” en Build Action:

Dicho archivo, contiene la siguiente estructura a modo de ejemplo:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Cálculo de Factoriales</title>    
</head>
<body>
    http://code.jquery.com/jquery-2.1.4.min.js
    <h1>Cálculo de Factoriales</h1>
    <div id='result'/>
    
        function printFactorial(number)
        {            
            var result = 1;
            var factorialNumber = parseInt(number);
            $('#result').empty();
            
            for (var i = 1; i ');
        }
    
</body>
</html>

Procederemos también, a crear la definición de nuestro archivo .xaml, el cual contendrá una caja de texto, un botón para invocar el método Javascript, y un WebView donde desplegaremos la información deseada:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:JavaScriptAndCSharp"
             x:Class="JavaScriptAndCSharp.MainPage">

    <StackLayout>
        <Label Text="Factorial" FontSize="Medium" HorizontalOptions="Center" />
        <StackLayout Orientation="Horizontal" HorizontalOptions="Center">
            <Label Text="Factorial Number: " VerticalOptions="Center" />
            <Entry x:Name="txtNumber" Text="5" WidthRequest="40" />
        </StackLayout>
        <Button x:Name="btnCallJS" Text="Call JavaScript" Clicked="OnbtnCallJSClicked"/>
        <WebView x:Name="webView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
    </StackLayout>

</ContentPage>

Ahora viene la parte interesante, en primer lugar, debemos de cargar la página HTML que deseemos, en nuestro caso, la página se llama test.html, por lo que crearemos una función dentro de nuestro archivo MainPage.xaml.cs, que lleve a cabo dicha carga, de la siguiente manera:

        HtmlWebViewSource LoadHTMLFileFromResource()
        {
            var source = new HtmlWebViewSource();

            // Carga el archivo HTML embebido como un recurso en el PCL
            var assembly = typeof(MainPage).GetTypeInfo().Assembly;
            var stream = assembly.GetManifestResourceStream("JavaScriptAndCSharp.test.html");
            using (var reader = new StreamReader(stream))
            {
                source.Html = reader.ReadToEnd();
            }
            return source;
        }

El código anterior, lo que hace es obtener el archivo HTML, y regresarlo como un órigen html para nuestro control WebView, debemos asignar dicha lectura en el constructor de nuestra página:

        public MainPage()
        {
            InitializeComponent();
            webView.Source = LoadHTMLFileFromResource();
        }

Por último, codificaremos el manejador de eventos del botón definido en nuestro código XAML, llamado “btnCallJS, de la siguiente forma:

        private void OnbtnCallJSClicked(object sender, EventArgs e)
        {        
            if (string.IsNullOrWhiteSpace(txtNumber.Text))
            {
                return;
            }
            int number = int.Parse(txtNumber.Text);
            webView.Eval(string.Format("printFactorial({0})", number));
        }

La forma de invocar las funciones dentro del archivo html, es a través de la función “Eval”, a la cual se le deben de pasar los parámetros obtenidos a través de la interfaz de usuario.

Con esto, tendrás una aplicación funcional que es capaz de invocar código Javascript:

Saludos.

Xamarin.Android Add new Android compiling versions (Target Frameworks)

If you are developing some application with Xamarin.Android, and a message like the following is displayed:

Severity    Code    Description    Project    File    Line    Suppression State
Error        Could not install package ‘Xamarin.GooglePlayServices.Maps 42.1001.0’. You are trying to install this package into a project that targets ‘MonoAndroid,Version=v6.0’, but the package does not contain any assembly references or content files that are compatible with that framework.

Regularly due to you do not have a version of the Target Framework compatbile, in the specific case above, it is because we must have a version of Android 7, version that from the properties of a project Xamarin.Android we can see that we do not have:

To resolve this issue, or simply because you want to add a new version of Android to compile, here are the steps to take:

1.- Open the “Android SDK Manager” tool:


2.- In the list of versions of Android, you should notice which are the ones you have installed, and which ones do not, selecting those versions that you want to install, for example, in my case, I want to install the version of Android 7.1 (API 25):

3.- Click on the Install button.


4.- Accept the license and Install.

5.- With this, when re-opening Visual Studio will already appear the new version with which we can compile our Xamarin.Android projects:

 

Xamarin.Android Añadir nuevas versiones de Android para compilación (Target Frameworks)

Si al estar desarrollando alguna aplicación con Xamarin.Android, se despliega un mensaje como el siguiente:

Severity    Code    Description    Project    File    Line    Suppression State
Error        Could not install package ‘Xamarin.GooglePlayServices.Maps 42.1001.0’. You are trying to install this package into a project that targets ‘MonoAndroid,Version=v6.0’, but the package does not contain any assembly references or content files that are compatible with that framework.

regularmente se debe a que no tienes una versión del Target Framework compatbile, en el caso específico anterior, se debe a que debemos de tener una versión de Android 7, versión que desde las propiedades de un proyecto Xamarin.Android podemos ver que no tenemos:

Para resolver dicho problema, ó simplemente porque deseas añadir una nueva versión de Android para compilar, éstos son los pasos a seguir:

1.- Abre la herramienta “Android SDK Manager”:

2.- En la lista de versiones de Android, debes fijarte cuáles son aquellos que tienes instalados, y cuáles no, seleccionando aquellas versiones que quieras instalar, por ejemplo, en mi caso, quiero instalar la versión de Android 7.1 (API 25):

3.- Dar click en el botón Instalar.

4.- Aceptar la licencia e Instalar.

5.- Con esto, al volver a abrir Visual Studio ya nos aparecerá la nueva versión con la que podremos compilar nuestros proyectos tipo Xamarin.Android:

Saludos.

Xamarin.Android – An unexpected error occurred trying to initialize Android Designer

Si tienes una instalación fresca de Visual Studio con un proyecto tipo Xamarin.Android, y te sale en la pantalla de Advertencias algo como:

“An unexpected error occurred trying to initialize Android Designer. Please verify the Android SDK path and the Java Development Kit…”

te recomiendo hacer lo siguiente:

Parte 1 – Dentro de Visual Studio

1.- Ve a las opciones de Visual Studio:

2.- En la Sección de Xamarin, ve a la opción de “Other” y da click sobre “Check Now”:

3.- Si aparece una actualización de Xamarin, da click sobre el botón “Download” para iniciar la descarga. Después de realizada la descarga, se lanzará el asistente de instalación, paso en el cual se debe cerrar Visual Studio:

4.- Llevar a cabo la instalación de las herramientas de Xamarin con el asistente de instalación.

Una vez terminado este proceso, toca el turno de actualizar las herramientas de Android:

Parte 2: Desde el Android SDK Manager

1.- Busca la herramienta SDK Manager desde Windows

2.- Busca en la sección de Tools, las opciones “Android SDK Tools”, y “Android SDK Platform tools”, y ve si está marcado de lado derecho con la leyenda “Update available…”.

3.- En caso de que sea así, deselecciona todos los paquetes que te aparezcan como recomendados (en la parte de abajo hay una etiqueta que dice “Deselect All”), y enfócate a instalar la actualización de dichos paquetes.

4.- Cierra la herramienta SDK Manager.

5.- Inicia de nuevo la herramienta SDK Manager, con lo cual se cargará de nuevo la lista.

6.- Verifica que a lado de las opciones buscadas en el paso 2, ya no aparezca la leyenda “Update available”, que puede aparecer tantas veces como desactualizadas tengas tus herramientas. Si sigue apareciendo la leyenda (que debe mostrar un número “rev x” diferente), vuelve al paso 2. Al final, debe mostrar una leyenda “Installed”.

7.- Una vez actualizadas tus herramientas, éste error debería desaparecer.

Saludos.

Agregando Intellisense a los archivos .axml para trabajar con Xamarin.Android en VS 2015

No podemos negar que las ayudas visuales de intellisense nos ahorran mucho tiempo con las sugerencias que realiza. Por ello, en este post vamos a ver los pasos para poder agregarlo en Visual Studio y trabajar con archivos .axml.

1.- Descargar el archivo alojado en este enlace.

2.- Descomprimir el archivo .rar.

3.- Pegar los 3 archivos descomprimidos en: (tuubicacióndeVS)/Xml/Schemas (En mi caso es: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Xml\Schemas)

4.- Si tienes abierto Visual Studio, reinicia.

5.- Dentro de Visual Studio, ir a XML -> Schemas

6.- Dentro de esta ventana, verificar que el archivo android-layout-xml.xsd se encuentre activo, como en la siguiente imagen:

Con esto, ya deberías tener Intellisense activo para poder autocompletar tu código:

Espero que sea de utilidad para más de uno.

Saludos.

Xamarin Forms: Consumiendo un servicio web basado en JSON Parte 3: Creando Creando la Vista

Para finalizar este proyecto, crearemos el formulario de la interfaz gráfica, y haremos los ajustes finales para tener nuestra aplicación corriendo.

En primer lugar, crearemos la última carpeta que nos hace falta llamada View:

image

En la nueva carpeta crearé un nuevo elemento del tipo Forms Xaml Page al cual llamaremos MainPage:

image

En el formulario creado, usaremos el siguiente código para el archivo MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="JsonWebServices.View.MainPage">
  <ContentPage.Content>
    <StackLayout Padding="30">
      <StackLayout Orientation="Horizontal">
        <Label Text="Latitude" WidthRequest="130"></Label>
        <Entry x:Name="txtLatitude" WidthRequest="150"></Entry>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Longitude" WidthRequest="130"></Label>
        <Entry x:Name="txtLongitude" WidthRequest="150"></Entry>
      </StackLayout>
      <Button x:Name="btnSearch" Clicked="OnClicked"
              WidthRequest="75" Text="Search" TextColor="White"
              BackgroundColor="Blue"></Button>
      <StackLayout Orientation="Horizontal">
        <Label Text="Location: " TextColor="Green"
               WidthRequest="130"></Label>
        <Label Text="{Binding StationName}"></Label>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Elevation: " TextColor="Green"
               WidthRequest="130"></Label>
        <Label Text="{Binding Elevation}"></Label>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Temperature: " TextColor="Green"
               WidthRequest="130"></Label>
        <Label Text="{Binding Temperature}"></Label>
      </StackLayout>
      <StackLayout Orientation="Horizontal">
        <Label Text="Humidity: " TextColor="Green"
               WidthRequest="130"></Label>
        <Label Text="{Binding Humidity}"></Label>
      </StackLayout>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

Por otra parte, en el archivo MainPage.xaml.cs, debemos definir una variable que será la instancia del ViewModel de la siguiente manera:

public MainPageViewModel vm;

Esta variable la inicializaremos dentro del constructor:

vm = new MainPageViewModel();

De igual forma, dentro del constructor debemos asignar el contexto de datos a dicha variable de la siguiente forma:

BindingContext = vm;

Por último, crearemos el manejador de eventos que hará la llamada al servicio web, en primer lugar, obtendremos la información de las cajas de texto, paso seguido definiremos la url del servicio web, y al último haremos la llamada a través del método especificado:

        public async void OnClicked(object sender, EventArgs e)
        {
            var longitude = double.Parse(txtLongitude.Text);
            var latitude = double.Parse(txtLatitude.Text);
            
            var url = string.Format(@"http://api.geonames.org/findNearByWeatherJSON?formatted=true&lat={0}&lng={1}&username=demo&style=full", latitude, longitude);
            await vm.GetWeatherAsync(url);
        }

quedando de la siguiente manera el archivo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JsonWebServices.ViewModel;
using Xamarin.Forms;

namespace JsonWebServices.View
{    
    public partial class MainPage : ContentPage
    {
        public MainPageViewModel vm;
        public MainPage()
        {
            vm = new MainPageViewModel();
            BindingContext = vm;
            InitializeComponent();
        }
        public async void OnClicked(object sender, EventArgs e)
        {
            var longitude = double.Parse(txtLongitude.Text);
            var latitude = double.Parse(txtLatitude.Text);
            
            var url = string.Format(@"http://api.geonames.org/findNearByWeatherJSON?formatted=true&lat={0}&lng={1}&username=demo&style=full", latitude, longitude);
            await vm.GetWeatherAsync(url);
        }
    }
}

Por último, modificaremos el constructor de la clase App para que asigne a la página MainPage como la página principal:

        public App()
        {
            // The root page of your application
            MainPage = new MainPage();
        }

Una vez terminada la codificación, podemos buscar coordenadas en cualquier aplicación de mapas para probar:

image

Ejecutaremos la aplicación e Insertaremos estas coordenadas, al presionar el botón search, nos mostrará el resultado correspondiente:

image

Definitivamente hay cosas que pueden ser mejoradas, pero queda como tarea para la casa, Espero que esta serie les haya gustado y servido. Recuerden que todo el proyecto lo pueden descargar desde aquí.

Saludos.

Xamarin Forms: Pre visualizando los formularios (Opción 2: Gorilla Player)

La segunda opción para llevar a cabo la pre visualización de los formularios, es a través de Gorilla Player. Aún se encuentra en estado beta, y para utilizarlo se requiere de una invitación, ya que es una beta privada, a mí me tardó alrededor de una semana en llegar el código desde que la solicité. Una vez que nos ha llegado el código, podemos realizar la descarga desde aquí. Procederemos a instalarlo, e inmediatamente nos aparecerá una ventana para loguearnos al servicio:

Screen Shot 05-03-16 at 11.25 AM

Posterior a este paso, nos aparecerá una venta con los 3 pasos que debemos llevar a cabo para utilizar el servicio:

1.- Verificar que Gorilla Player se encuentre corriendo desde la barra de tareas:

Screen Shot 05-04-16 at 08.40 AM

2.- Se requiere desplegar la aplicación derivada de la solución Player.sln, a cada uno de los emuladores y dispositivos donde vayamos a llevar a cabo pruebas:

2a) Abrir la solución desde el Wizard de Gorilla Player:

Screen Shot 05-04-16 at 08.43 AM

Screen Shot 05-04-16 at 08.44 AM

2b) Desplegar el dispositivo en el emulador o dispositivo físico correspondiente(Debemos asegurarnos de descargar los paquetes de nuget faltantes:

Screen Shot 05-04-16 at 09.15 AM

3c) La aplicación tratará de encontrar el servidor de Gorilla Player en el equipo que tengamos conectado. Una vez realizado este paso, nos indicará que se encuentra listo para realizar las pre visualizaciones necesarias:

Screenshot_2016-05-04-09-22-11

3.- Probar los ejemplos que vienen en la solución:

3a) Abrir la solución de ejemplo:

Screen Shot 05-04-16 at 09.30 AM

3b) De nueva cuenta, restaurar los paquetes de nuget:

Screen Shot 05-04-16 at 09.30 AM 001

3c) Un ícono de un gorila nos mostrará que estamos conectados y listos para probar el código XAML de nuestro proyecto:

Screen Shot 05-04-16 at 09.34 AM

3d) Ahora, basta con que abramos la aplicación recién instalada llamada Gorilla Player desde nuestro emulador o dispositivo, y ejecutar el comando Guardar desde el formulario que queremos probar desde Visual Studio (Ctrl + S) para que nos despliegue el resultado en el dispositivo o emulador deseado:

Screenshot_2016-05-04-09-35-43

Al llevar a cabo algún cambio, bastará con volver a presionar Ctrl + S para verificar el cambio en tiempo real:

Screenshot_2016-05-04-09-37-49

Podemos ahora abrir algún proyecto desarrollado previamente, y ver en tiempo real si existe algún problema de diseño como en el siguiente caso:

Screenshot_2016-05-04-10-12-00

Este formulario, lo podemos corregir de una manera muy sencilla y rápida con ayuda de Gorilla Player:

Screenshot_2016-05-04-10-15-46

Como podemos ver, llevar a cabo la realización de formularios a través de Gorilla Player es una excelente alternativa para ahorrarnos muchísimo tiempo. La única advertencia que hay que tener en cuenta, es que el servicio, seguramente tendrá un costo extra en la versión final.

Por último, como advertencia, Visual Studio en conjunto con Gorilla Player se me congela si el proyecto se encuentra alojado en un repositorio GitHub.

Saludos.

Xamarin Forms: Pre visualizando los formularios (Opción 1)

Una de las características más solicitadas por los desarrolladores en Xamarin Forms, es el poder ver en tiempo de diseño sus formularios. Aunque en el evento “Xamarin Evolve 2016” se ha anunciado un pre visualizador oficial, aún se encuentra en estado Alpha.

Una de las opciones para llevar a cabo una previsualización de nuestros formularios (aunque no es en tiempo real), es la utilización del proyecto Windows Phone Forms to Xamarin Forms, el cual nos permite convertir un formulario desarrollado para Windows Phone en un formulario de Xamarin. Aquí van las instrucciones:

1.- Creando el formulario en un proyecto tipo Windows Phone

Debemos crear un nuevo formulario en un proyecto tipo Windows Phone, o bien utilizar uno existente:

Screen Shot 04-28-16 at 10.25 AM

Screen Shot 04-28-16 at 10.25 AM 001

Screen Shot 04-28-16 at 10.27 AM

Una vez agregado el archivo en el proyecto, podemos comenzar a diseñarlo con ayuda del diseñador integrado para este tipo de proyectos, en mi caso, crearé un formulario que quedará de la siguiente manera:

Screen Shot 04-28-16 at 10.28 AM

con el código correspondiente:

<phone:PhoneApplicationPage
    x:Class="JsonWebServices.WinPhone.WeatherPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="XAMARIN" FontSize="20"/>
            <TextBlock Text="Weather App" Margin="9,-7,0,0" FontSize="72" />
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel Orientation="Vertical">
                <StackPanel Orientation="Horizontal">
                    <TextBlock>Latitud</TextBlock>
                    <TextBox Width="300" x:Name="txtLatitude"></TextBox>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock>Longitud</TextBlock>
                    <TextBox Width="300" x:Name="txtLongitude"></TextBox>
                </StackPanel>
                <Button Content="Obtener Datos" Click="ButtonBase_OnClick"></Button>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Width="130">Ubicación</TextBlock>
                    <TextBlock Text="{Binding StationName}"></TextBlock>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Width="130">Elevación</TextBlock>
                    <TextBlock Text="{Binding Elevation}"></TextBlock>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Width="130">Temperatura</TextBlock>
                    <TextBlock Text="{Binding Temperature}"></TextBlock>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Width="130">Humedad</TextBlock>
                    <TextBlock Text="{Binding Humidity}"></TextBlock>
                </StackPanel>
            </StackPanel>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

2.- Leer la documentación y descargar la herramienta

El autor de la herramienta es Jonathan Yates, y podemos encontrar la entrada principal de la herramienta aquí. Aunque los enlaces de la página a la página de OneDrive llevan a un link desactualizado, puedes enviarle un mail a pete@petevickers.co.uk para solicitarle una copia de la herramienta, quien, en mi caso particular me respondió mi correo de forma rápida.

3.- Utilizando la herramienta

Una vez que hemos instalado la herramienta, nos aparecerá algo parecido a esto:

Screen Shot 04-28-16 at 10.37 AM

Lo que haremos en este caso en particular, será colocarle un espacio de nombres dentro del proyecto donde se alojará el formulario, seleccionaremos la ruta al archivo, y automáticamente nos generará una ruta para un archivo destino:

Screen Shot 04-28-16 at 10.40 AM

Posteriormente, debemos dar click en el botón “Generate”, lo cual nos mostrará un mensaje si la conversión es correcta:

Screen Shot 04-28-16 at 10.40 AM 001

El resultado será el siguiente código, que podremos reutilizar para no iniciar nuestros desarrollos desde cero:

<?xml version="1.0" encoding="utf-8" ?>
<!--Code generated by 'WP to XF' created by GUI Innovations Limited-->
<!--For more details, enhancement requests, bugs etc.  please email-->
<!--             pete@gui-innovations.com  - Thanks                -->
<formtype xmlns=|http://xamarin.com/schemas/2014/forms|
             xmlns:x=|http://schemas.microsoft.com/winfx/2009/xaml|
             x:Class=|PageName|>

<StackLayout Orientation="Vertical"
      VerticalOptions="FillAndExpand"
      HorizontalOptions="FillAndExpand"
      Padding="10,40,10,30"
      Spacing="10">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" BackgroundColor="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackLayout Grid.Row="0" Padding="12,17,0,28">
            <Label Text="XAMARIN" FontSize="20"/>
            <Label Text="Weather App"  FontSize="72" />
        </StackLayout>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Padding="12,0,12,0">
            <StackLayout Orientation="Vertical">
                <StackLayout Orientation="Horizontal">
                    <Label>Latitud</Label>
                    <Entry WidthRequest="300" x:Name="txtLatitude"></Entry>
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label>Longitud</Label>
                    <Entry WidthRequest="300" x:Name="txtLongitude"></Entry>
                </StackLayout>
                <Button Text="Obtener Datos"></Button>
                <StackLayout Orientation="Horizontal">
                    <Label WidthRequest="130">Ubicación</Label>
                    <Label Text="{Binding StationName}"></Label>
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label WidthRequest="130">Elevación</Label>
                    <Label Text="{Binding Elevation}"></Label>
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label WidthRequest="130">Temperatura</Label>
                    <Label Text="{Binding Temperature}"></Label>
                </StackLayout>
                <StackLayout Orientation="Horizontal">
                    <Label WidthRequest="130">Humedad</Label>
                    <Label Text="{Binding Humidity}"></Label>
                </StackLayout>
            </StackLayout>
        </Grid>
    </Grid>
</StackLayout>
</ContentPage>

Cabe destacar que la herramienta es una muy buena ayuda para no iniciar desde cero nuestros formularios, o bien, si queremos reutilizar formularios existentes.

Saludos.

Xamarin Forms: Consumiendo un servicio web basado en JSON Parte 2: Creando el ViewModel

En este post nos enfocaremos a crear el ViewModel del proyecto. En primer lugar, crearemos una carpeta llamada ViewModel, donde alojaremos nuestro código correspondiente al ViewModel.

Crearemos una clase llamda MainPageViewModel, a la cual implementaremos la interfaz: INotifyPropertyChanged, de la siguiente manera:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using JsonWebServices.Annotations;

namespace JsonWebServices.ViewModel
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        #region InotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

Para poder llevar a cabo la notificación de un cambio en una de las propiedades para poder comunicársela a la interfaz gráfica a través de un binding, debemos crear una propiedad  por cada valor que queramos notificar a la interfaz gráfica, seguido de la llamada al método OnPropertyChanged(), como en el siguiente ejemplo:

        private string _stationName;
        public string StationName
        {
            get
            {
                return _stationName;
            }

            set
            {
                _stationName = value;
                OnPropertyChanged();
            }
        }

Para ejemplos demostrativos, implementaremos las propiedades de StationName, Elevation, Temperature y Humidity, de la siguiente forma

        #region Properties
        private string _stationName;
        private int _elevation;
        private string _temperature;
        private int _humidity;
        public string StationName
        {
            get
            {
                return _stationName;
            }

            set
            {
                _stationName = value;
                OnPropertyChanged();
            }
        }
        public int Elevation
        {
            get
            {
                return _elevation;
            }

            set
            {
                _elevation = value;
                OnPropertyChanged();
            }
        }

        public string Temperature
        {
            get
            {
                return _temperature;
            }

            set
            {
                _temperature = value;
                OnPropertyChanged();
            }
        }

        public int Humidity
        {
            get
            {
                return _humidity;
            }

            set
            {
                _humidity = value;
                OnPropertyChanged();
            }
        }
        #endregion

Para la siguiente parte, debemos instalar un par de paquetes de nuget, los cuales puedes instalar a través de la Consola de paquetes de nuget, apuntando al proyecto Portable:

Screen Shot 04-25-16 at 09.46 AM

los cuales son:

Install-Package Microsoft.Net.Http

Install-Package Newtonsoft.Json

 

Posteriormente, debemos crear un método llamado GetWeatherAsync que se encargue de llevar a cabo la solicitud al sitio web, a través de una instancia de HttpClient. y su posterior deserialización de la siguiente forma:

        public async Task GetWeatherAsync(string url)
        {
            //Creamos una instancia de HttpClient
            var client = new HttpClient();
            //Asignamos la URL
            client.BaseAddress = new Uri(url);
            //Llamada asíncrona al sitio
            var response = await client.GetAsync(client.BaseAddress);
            //Nos aseguramos de recibir una respuesta satisfactoria
            response.EnsureSuccessStatusCode();
            //Convertimos la respuesta a una variable string
            var jsonResult = response.Content.ReadAsStringAsync().Result;
            //Se deserializa la cadena y se convierte en una instancia de WeatherResult
            var weather = JsonConvert.DeserializeObject<WeatherResult>(jsonResult);
            //Asignamos el nuevo valor de las propiedades
            SetValue(weather);
        }

Por último, agregaremos un método llamado SetValue, que nos servirá para actualizar las propiedades de la clase contenida en el ViewModel, de la siguiente forma:

        private void SetValue(WeatherResult weather)
        {
            var stationName = weather.WeatherObservation.StationName;
            var elevation = weather.WeatherObservation.Elevation;
            var temperature = weather.WeatherObservation.Temperature;
            var humidity = weather.WeatherObservation.Humidity;

            StationName = stationName;
            Elevation = elevation;
            Temperature = temperature;
            Humidity = humidity;
        }

El resultado final de la clase, deberá verse de la siguiente forma:

using System;
using System.ComponentModel;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using JsonWebServices.Annotations;
using JsonWebServices.Model;
using Newtonsoft.Json;

namespace JsonWebServices.ViewModel
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        #region Properties
        private string _stationName;
        private int _elevation;
        private string _temperature;
        private int _humidity;
        public string StationName
        {
            get
            {
                return _stationName;
            }

            set
            {
                _stationName = value;
                OnPropertyChanged();
            }
        }
        public int Elevation
        {
            get
            {
                return _elevation;
            }

            set
            {
                _elevation = value;
                OnPropertyChanged();
            }
        }

        public string Temperature
        {
            get
            {
                return _temperature;
            }

            set
            {
                _temperature = value;
                OnPropertyChanged();
            }
        }

        public int Humidity
        {
            get
            {
                return _humidity;
            }

            set
            {
                _humidity = value;
                OnPropertyChanged();
            }
        }
        #endregion

        #region Methods
        public async Task GetWeatherAsync(string url)
        {
            //Creamos una instancia de HttpClient
            var client = new HttpClient();
            //Asignamos la URL
            client.BaseAddress = new Uri(url);
            //Llamada asíncrona al sitio
            var response = await client.GetAsync(client.BaseAddress);
            //Nos aseguramos de recibir una respuesta satisfactoria
            response.EnsureSuccessStatusCode();
            //Convertimos la respuesta a una variable string
            var jsonResult = response.Content.ReadAsStringAsync().Result;
            //Se deserializa la cadena y se convierte en una instancia de WeatherResult
            var weather = JsonConvert.DeserializeObject<WeatherResult>(jsonResult);
            //Asignamos el nuevo valor de las propiedades
            SetValue(weather);
        }

        private void SetValue(WeatherResult weather)
        {
            var stationName = weather.WeatherObservation.StationName;
            var elevation = weather.WeatherObservation.Elevation;
            var temperature = weather.WeatherObservation.Temperature;
            var humidity = weather.WeatherObservation.Humidity;

            StationName = stationName;
            Elevation = elevation;
            Temperature = temperature;
            Humidity = humidity;
        }
        #endregion

        #region InotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

En la siguiente entrada, nos encargaremos de la parte de la vista. Cualquier duda o comentario, no dudes en escribirlo, y recuerda que el código fuente del ejemplo lo puedes encontrar aquí.

Saludos.

Xamarin Forms: Consumiendo un servicio web basado en JSON Parte 1: Creando el Modelo

Para llevar a cabo el consumo de un servicio web basado en Json, en primer lugar, debemos tener disponible el servicio mismo. Para llevar a cabo esta demostración, utilizaré los servicios alojados en este enlace.

Esta página nos permite utilizar más de 30 servicios web diferentes, cuya respuesta puede ser XML, JSON, RDF, CSV, TXT, RSS ó KML, basta con dar click sobre el enlace requerido para que se nos muestre un ejemplo de la respuesta del servicio. Yo utilizaré el servicio findNearByWeather.

Screen Shot 04-20-16 at 09.52 AM

Screen Shot 04-20-16 at 09.53 AM

Para iniciar el desarrollo de la aplicación, debemos crear un proyecto de tipo Xamarin.Forms, de tipo Portable:

Screen Shot 04-20-16 at 10.14 AM

Una vez creado el proyecto, crearemos 1 carpeta llamada Model, y dentro de esta, crearemos una clase que aloje las propiedades que correspondan al modelo del archivo Json, a la cual llamaremos WeatherObservation.

Ahora bien, para llevar a cabo la creación de las propiedades dentro de la clase, podríamos pensar que debemos de escribirlas a mano una por una, sin embargo, Visual Studio nos ofrece la posibilidad de generar el modelo a partir del archivo json. Una vez copiado el archivo json, debemos pegarlo a través del menú Edit –> Paste Special –> Paste JSON As Classes, lo cual nos generará el siguiente código:

namespace JsonWebServices.Model
{

    public class Rootobject
    {
        public Weatherobservation weatherObservation { get; set; }
    }

    public class Weatherobservation
    {
        public int elevation { get; set; }
        public float lng { get; set; }
        public string observation { get; set; }
        public string ICAO { get; set; }
        public string clouds { get; set; }
        public string dewPoint { get; set; }
        public string cloudsCode { get; set; }
        public string datetime { get; set; }
        public string countryCode { get; set; }
        public string temperature { get; set; }
        public int humidity { get; set; }
        public string stationName { get; set; }
        public string weatherCondition { get; set; }
        public int windDirection { get; set; }
        public int hectoPascAltimeter { get; set; }
        public string windSpeed { get; set; }
        public float lat { get; set; }
    }

}

A continuación, renombraremos la clase Rootobject por WeatherResult. y modificaremos las propiedades para que inicien con mayúsculas, quedando nuestro modelo de la siguiente forma:

namespace JsonWebServices.Model
{

    public class WeatherResult
    {
        public Weatherobservation WeatherObservation { get; set; }
    }

    public class Weatherobservation
    {
        public int Elevation { get; set; }
        public float Lng { get; set; }
        public string Observation { get; set; }
        public string Icao { get; set; }
        public string Clouds { get; set; }
        public string DewPoint { get; set; }
        public string CloudsCode { get; set; }
        public string Datetime { get; set; }
        public string CountryCode { get; set; }
        public string Temperature { get; set; }
        public int Humidity { get; set; }
        public string StationName { get; set; }
        public string WeatherCondition { get; set; }
        public int WindDirection { get; set; }
        public int HectoPascAltimeter { get; set; }
        public string WindSpeed { get; set; }
        public float Lat { get; set; }
    }

}

En el siguiente post, nos enfocaremos a crear e ViewModel correspondiente a la aplicación.

El proyecto con los cambios que vayamos haciendo lo pueden encontrar aquí.

Saludos.

Xamarin Forms: El método Device.OnPlatform

Cuando trabajamos en un desarrollo multiplataforma, a veces es necesario que ciertas propiedades se comporten de forma diferente de acuerdo a la plataforma en la que se encuentre ejecutándose.

Una clase que nos puede ayudar a alcanzar dicho objetivo, es la clase estática Device, la cual dentro de sus métodos incluye un método llamado OnPlatform, cuya definición indica que “Ejecuta diferentes acciones dependiendo en el Xamarin.QcuikUI.TargetOS Form que se encuentre ejecutando.

Es decir, que con dicho método, podremos asignar que una propiedad Text aparezca con un texto diferente en cada plataforma, que un tamaño de letra sea diferente en cada plataforma, etc.

La documentación indica que los parámetros de dicho méotod, son opcionales y van ordenados de la siguiente forma:

iOS
(optional) The Action to execute on iOS.
Android
(optional) The Action to execute on Android.
WinPhone
(optional) The Action to execute on WinPhone.
Default
(optional) The Action to execute if no Action was provided for the current OS.

Veamos un ejemplo práctico con un proyecto recién creado en Xamarin Forms:

            MainPage = new ContentPage
            {
                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    Children = {
                        new Label {
                            XAlign = TextAlignment.Center,
                            Text = "Welcome to Xamarin Forms!"
                        }
                    }
                }
            };

El código anterior, muestra el código que es creado en un nuevo proyecto tipo Xamarin Forms, lo modificaremos para que muestre un texto de acuerdo a la plataforma en específico:

                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    Children = {
                        new Label {
                            XAlign = TextAlignment.Center,
                            Text = Device.OnPlatform("IOS", "ANDROID", "WINPHONE")
                        }
                    }
                }

O podemos hacer que un control sea o no visible de acuerdo a la plataforma:

                        new Label {
                            XAlign = TextAlignment.Center,
                            Text = "Welcome to Xamarin Forms!",                            
                            IsVisible = Device.OnPlatform(true,false,true)
                        }

Incluso, podemos implementar un manejador de eventos distinto para un botón en cada plataforma:

            var button1 = new Button
            {
                Text = "Click Me!"
            };
            Device.OnPlatform(
                iOS: () => button1.Clicked += (sender, e) =>
                {
                    DisplayAlert("IOS", "Estoy en un Iphone!", "Ok");
                },
                Android: () => button1.Clicked += (sender, e) =>
                {
                    DisplayAlert("Android", "Estoy en un Androide!", "Ok");
                },
                WinPhone: () => button1.Clicked += (sender, e) =>
                {
                    DisplayAlert("WinPhone", "Estoy en un Lumia!", "Ok");
                }
            );

 

Espero que les sea de utilidad

 

¡Saludos!

Utilizando la Biblioteca SqlHelper (3/3)

Ejecutar una consulta y devolver un sólo valor:

Como bien es sabido, para ejecutar una consulta y devolver un sólo valor a través de un SqlCommand, debemos ejecutar un el método ExecuteNonQuery().

Es fácil realizar una ejecución de este método de forma controlada a través de la biblioteca SqlHelper, ya que contiene métodos que nos facilitarán dicha tarea. Esto nos permitirá devolver un valor con tan sólo 2 líneas de código:

        private void StartScalarDemo()
        {
            var query = "SELECT CompanyName FROM Customers WHERE CustomerID = 'BLAUS'";
            var result = SqlHelper.ExecuteScalar(GlobalData.ConnectionString, CommandType.Text, query);
            Debug.WriteLine(result);                               
        }

En primer lugar, hemos de definir la sentencia a ejecutar, mientras que en la siguiente ejecutaremos el método denominado ExecuteNonQuery que se encargará de llevar a cabo todo el proceso correspondiente al manejo de apertura y cierre de la base de datos, así como la gestión de errores.

Ejecutar una consulta del tipo NonQuery:

Si lo que deseamos es llevar a cabo la ejecución de una consulta que no devuelva información de la base de datos (tal como un insert o un delete), la lógica será similar al ejemplo anterior, con la diferencia de que el método que hemos de ejecutar es ExecuteNonQuery, que nos devolverá el número de filas afectadas, y el cual ejecutaremos de la siguiente forma en el caso de querer insertar información:

        private void StartNonQueryDemo1()
        {
            String query = "";
            query = query + "INSERT INTO [dbo].[Customers] " + "\n";
            query = query + "           ([CustomerID] " + "\n";
            query = query + "           ,[CompanyName] " + "\n";
            query = query + "           ,[ContactName] " + "\n";
            query = query + "           ,[ContactTitle] " + "\n";
            query = query + "           ,[Address] " + "\n";
            query = query + "           ,[City] " + "\n";
            query = query + "           ,[Region] " + "\n";
            query = query + "           ,[PostalCode] " + "\n";
            query = query + "           ,[Country] " + "\n";
            query = query + "           ,[Phone] " + "\n";
            query = query + "           ,[Fax]) " + "\n";
            query = query + "     VALUES " + "\n";
            query = query + "           ('XYZ' " + "\n";
            query = query + "           ,'HECTORS COMPANY' " + "\n";
            query = query + "           ,'HÉCTOR PÉREZ' " + "\n";
            query = query + "           ,'M.C.C' " + "\n";
            query = query + "           ,'AV. HOGWARTS' " + "\n";
            query = query + "           ,'MAGICLAND' " + "\n";
            query = query + "           ,'REGIONLAND' " + "\n";
            query = query + "           ,'99999' " + "\n";
            query = query + "           ,'UK' " + "\n";
            query = query + "           ,'2222' " + "\n";
            query = query + "           ,'2222')";

            var result = SqlHelper.ExecuteNonQuery(GlobalData.ConnectionString, CommandType.Text, query);
            Debug.WriteLine("Registros agregados: {0}", result);
        }

En caso de desear eliminar el registro insertado en el ejemplo anterior, o bien, algún otro, debemos hacer una ejecución como en el siguiente ejemplo:

        private void StartNonQueryDemo2()
        {
            String query = "DELETE FROM [Customers] WHERE [CustomerID] = 'XYZ'";            

            var result = SqlHelper.ExecuteNonQuery(GlobalData.ConnectionString, CommandType.Text, query);
            Debug.WriteLine("Filas eliminadas: {0}", result);
        }

Hemos visto que la utilización de la biblioteca SqlHelper es de mucha ayuda a la hora de programar, lo único que falta es que la integres a tus proyectos si te ha gustado. De nuevo, dejo el link de github si deseas integrar una biblioteca de clases de utilidades que se irán agregando poco a poco.

Saludos.

Generando una clase intermedia a través de wsdl.exe para conectarnos a un servicio web .asmx

Como bien sabemos, la forma más sencilla para agregar y posteriormente consumir un servicio web, es a través del menú contextual de Visual Studio:

Screen Shot 03-22-16 at 11.00 AM

Sin embargo, existen otras formas de consumir un servicio web de manera sencilla y transparente. Una de ellas puede ayudarnos además, para analizar, estudiar y aprender del código generado. Esta forma es a través de la herramienta wsdl.exe, que se encuentra en la siguiente ruta:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools

Debemos navegar a través de una consola de comandos a la dirección antes especificada, y utilizar algunas de las opciones disponibles. La simbología para utilizar la herramienta, es:

wsdl.exe <opciones> <dirección_url o ruta_de_acceso> …

Si deseamos ver las opciones disponibles, bastará con escribir simplemente wsdl.exe:

Screen Shot 03-22-16 at 11.07 AM

Vamos a utilizar el servicio “Weight Unit Convertor”, disponible en la página http://webservicex.net/, para generar la clase correspondiente. Lo primero que debemos hacer, es navegar al servicio web, donde nos será mostrado el Endpoint:

Screen Shot 03-22-16 at 11.10 AM

Dicho Endpoint, será el que utilizaremos para generar nuestra clase, debiendo colocarlo de la siguiente forma en la consola de comandos:

wsdl http://www.webservicex.net/ConvertWeight.asmx?WSDL

Lo que nos generará una clase en el directorio mismo de la herramienta:

Screen Shot 03-22-16 at 11.15 AM

Podemos agregar la clase generada a un proyecto desde Visual Studio, donde nos mostrará algunos errores si no hemos agregado la biblioteca System.Web.Services, por lo que es necesario que se encuentre dentro del proyecto donde utilizaremos el servicio web.

Screen Shot 03-22-16 at 11.17 AM

Con esto, podremos utilizar la clase generada como cualquier otra:

Screen Shot 03-22-16 at 11.23 AM 001

Además de que funcionará de manera correcta:

Screen Shot 03-22-16 at 11.23 AM

¡Saludos!

Utilizando la Biblioteca SqlHelper (2/n)

Ejecutar consulta y llenar un DataReader:

Para llevar a cabo la ejecución de una consulta y rellenar un DataReader, disponemos de los siguientes métodos:

Screen Shot 03-19-16 at 12.14 PM

En esta demostración, utilizaremos el método:

public static System.Data.SqlClient.SqlDataReader ExecuteReader(string connectionString, System.Data.CommandType commandType, string commandText)

Podemos observar, que se nos pide como primer parámetro una cadena de conexión, como segundo el tipo de comando (si es consulta normal o un stored procedure), y como tercer, la consulta como tal.

En primer lugar, definiremos en una variable la consulta que deseamos ejecutar:

var sqlQuery = "SELECT * FROM Customers";

En segundo lugar, llamaremos al método que nos interesa, pasándole como referencia la cadena de conexión que definimos en el post anterior, seguido por el tipo de enumeración que deseamos aplicar, y la consulta definida previamente. Cabe destacar, que utilizaremos un using para cerrar la conexión y eliminar la instancia una vez que la dejemos de utilizar:

 using (var newDataReader = SqlHelper.ExecuteReader(
                GlobalData.ConnectionString,
                CommandType.Text, sqlQuery))

Por último, haremos un recorrido por el datareader e imprimiremos la información deseada:

while (newDataReader.Read())
                {
                    var customerInfo = string.Format(
                        "Company Name: {0}, ContactName: {1}",
                        newDataReader.GetString(1),
                        newDataReader.GetString(2));
                    Debug.WriteLine(customerInfo);                    
                }

Quedando el código completo del método, de la siguiente manera:

 private void StartDataReaderDemo()
        {
            //Utilizando SqlHelper para llenar un DataReader
            var sqlQuery = "SELECT * FROM Customers";
            using (var newDataReader = SqlHelper.ExecuteReader(
                GlobalData.ConnectionString,
                CommandType.Text, sqlQuery))
            {
                while (newDataReader.Read())
                {
                    var customerInfo = string.Format(
                        "Company Name: {0}, ContactName: {1}",
                        newDataReader.GetString(1),
                        newDataReader.GetString(2));
                    Debug.WriteLine(customerInfo);                    
                }
            }


        }

Ejecutar consulta a un Stored Procedure y llenar un DataReader:

La forma para llevar a cabo una consulta a un procedimiento almacenado, conlleva básicamente los mismos pasos que anteriormente, con la diferencia, que debemos especificar el nombre del procedimiento almacenado en lugar de la consulta:

var sqlQuery = "Sales by Year";

En segundo lugar, debemos definir un arreglo de tipo SqlParameter, definiendo los parámetros que deseamos pasar:

            var param1 = new SqlParameter {ParameterName = "@Beginning_Date", Value = new DateTime(1995, 1, 1) };
            var param2 = new SqlParameter { ParameterName = "@Ending_Date", Value = new DateTime(1997, 1, 1)};
            SqlParameter[] parameters = new[] {param1, param2};

Lo demás, es prácticamente lo mismo, el código completo del método se encuentra a continuación:

        private void StartDataReaderDemo2()
        {
            //Utilizando SqlHelper para llenar un DataReader a través de un stored procedure
            var sqlQuery = "Sales by Year";
            var param1 = new SqlParameter {ParameterName = "@Beginning_Date", Value = new DateTime(1995, 1, 1)};
            var param2 = new SqlParameter {ParameterName = "@Ending_Date", Value = new DateTime(1997, 1, 1)};
            SqlParameter[] parameters = new[] {param1, param2};
            using (var newDataReader = SqlHelper.ExecuteReader(
                GlobalData.ConnectionString,
                CommandType.StoredProcedure, sqlQuery, parameters))
            {
                while (newDataReader.Read())
                {
                    var customerInfo = string.Format(
                        "Order ID: {0}, Subtotal{1}",
                        newDataReader.GetInt32(1),
                        newDataReader.GetDecimal(2));
                    Debug.WriteLine(customerInfo);
                }
            }
        }

Utilizando la Biblioteca SqlHelper (1/n)

En una publicación pasada, agregamos a nuestra solución una clase que puede llevar a cabo la ejecución de consultas a un servidor SQL Server, vamos a ver en esta entrada cómo utilizar algunos de los métodos incluidos en la clase, tomando como la base de datos Northwind como ejemplo.

Ejecutar consulta y llenar un DataSet:

Si se quiere llenar un DataSet para trabajar posteriormente con él, podemos ejecutar el método denominado “ExecuteDataset”, el cual tiene 8 sobrecargas (Dar click en la imagen para ver en tamaño real):

Screen Shot 03-16-16 at 11.06 AM

La clase nos da una amplia gama de sobrecargas para poder pasar todo tipo de parámetros necesarios para llevar a cabo la ejecución de una consulta y posterior llenado de un Dataset, como ejemplo, vamos a ocupar el segundo método:

SqlHelper.ExecuteDataset(string, System.Data.CommandType, string)

cuya definición es:

public static System.Data.DataSet ExecuteDataset(string connectionString, System.Data.CommandType commandType, string commandText)

Es decir, debemos pasar como primer parámetro una cadena de conexión (Existe otro método para pasar directamente un objeto ConnectinString), para cuestiones de simplicidad, he creado una clase que mantiene la cadena de conexión centralizada:

    public static class GlobalData
    {
        public static string ConnectionString { get; set; }
        static GlobalData()
        {
            ConnectionString = @"Data Source=.\SQLSERVER;Initial Catalog=Northwind;Integrated Security=True";
        }
    }

Debemos crear una variable para almacenar la consulta que deseemos ejecutar, en mi caso será la siguiente:

var sqlQuery = "SELECT * FROM Customers";

Listo, ya podremos utilizar el método con la información previamente definida, colocando el resultado de la ejecución de tipo DataSet en una nueva variable:

            var newDataSet = SqlHelper.ExecuteDataset(
                GlobalData.ConnectionString,
                CommandType.Text, sqlQuery);
            var customers = newDataSet.Tables[0];

Si deseamos consultar el resultado, debemos obtener una de las tablas de la consulta en primer lugar:

var customers = newDataSet.Tables[0];

para posteriormente utilizar Linq para llevar a cabo la consulta (Debemos utilizar un método especial llamado .AsEnumerable para poder realizar consultas con Linq, que se encuentra en el ensamblado System.Data.DataSetExtensions), y como buena práctica, definir un nuevo tipo anónimo para poder utilizar las propiedades desde código:

            var query = from customer in customers.AsEnumerable()
                        select new
                        {
                            CompanyName = customer.Field<string>("CompanyName"),
                            ContactName = customer.Field<string>("ContactName")
                        };

Por último, podemos recorrer el resultado de la consulta Linq e imprimir la información necesaria:

            foreach (var customer in query)
            {
                Debug.WriteLine(customer.CompanyName);
            }

Recuerden que el código se irá complementando en el repositorio de GitHub:

https://github.com/hprez21/Hyrule

 

En la próxima entrada seguiremos viendo más métodos

¿Cómo depurar una aplicación de forma remota con Visual Studio 2015? (aplica para versiones anteriores también)

Aunque existe una guía oficial para llevar a cabo este procedimiento, en esta entrada detallaré los pasos necesarios para llevar a cabo la depuración de una aplicación de forma remota.

Prerrequisitos:

Aunque no es indispensable, es altamente recomendable tener activada y configurada la opción de Conexión a Escritorio Remoto en el equipo donde llevaremos a cabo las pruebas de la aplicación.

Configurando la herramienta:

En primer lugar, debemos instalar la herramienta de depuración remota para Visual Studio 2015. Se pueden elegir las herramientas para las plataformas x64, x86 y ARM.

Una vez instalado en la máquina remota, debemos iniciar el asistente para configurar la herramienta:

Screen Shot 03-04-16 at 08.46 PM

Esto nos desplegará una ventana donde podremos configurar si deseamos que la aplicación se ejecute como un servicio en la máquina de pruebas. En mi caso lo dejaré deseleccionado.

Screen Shot 03-04-16 at 08.47 PM

En la siguiente ventana, se nos pregunta la configuración que deseamos aplicar para el firewall de acuerdo al tipo de red seleccionada. Para cuestiones prácticas dejaré seleccionadas todas las redes.

Screen Shot 03-04-16 at 08.48 PM

 

Después de este paso, podremos dar click en el botón Finalizar. Con esto hemos configurado la herramienta para poder llevar a cabo pruebas de nuestras aplicaciones en una máquina remota.

Preparándonos para la prueba:

Dentro de Visual Studio, debemos irnos a las propiedades del proyecto (no de la solución):

Screen Shot 03-04-16 at 08.55 PM

Dentro de las propiedades del proyecto, debemos irnos al apartado “Debug”, y en la sección de “Start Options”, habilitar “Use remote machine”. En la casilla de la derecha, debemos utilizar de preferencia la dirección IP de la máquina remota.

Screen Shot 03-04-16 at 08.58 PM

Paso siguiente, debemos hacer un rebuild de nuestro proyecto (hay que checar que se encuentre en modo Debug).

En seguida, debemos crear una estructura en la máquina remota que sea idéntica a nuestra carpeta bin de nuestra máquina local. Es decir, si la carpeta Debug de mi proyecto se encuentra en C:\Users\hprez\Documents\Visual Studio 2015\Projects\Blog\ExcelSample\ExcelSample\bin\Debug, debemos crear esta misma estructura en la máquina remota, tal como en el siguiente ejemplo:

Máquina local (con VS)

Screen Shot 03-04-16 at 09.07 PM

Máquina remota (Sin VS)

Screen Shot 03-04-16 at 09.09 PM

Por último, deberemos copiar el contenido de la carpeta Debug de nuestro proyecto, y pegarlo en la carpeta Debug de la máquina remota:

Screen Shot 03-04-16 at 09.11 PM

Una vez que estemos listos, deberemos iniciar la herramienta de depuración remota en la máquina remota, la cual, nos deberá indicar que se encuentra esperando nuevas conexiones:

Screen Shot 03-04-16 at 09.14 PM

Finalmente, iniciaremos nuestro proyecto desde Visual Studio, y todo deberá funcionar a la perfección:

Screen Shot 03-04-16 at 09.16 PM 001

 

Cabe aclarar que si deseamos depurar la aplicación a través de un breakpoint en un punto específico de la aplicación, debemos regenerar el proyecto y copiar de nuevo el contenido de la carpeta bin, esto es debido a que se tiene que regenerar la información de depuración.

Espero que a más de uno le sea de utilidad.

Saludos.

Manipulando archivos de Excel con C# sin morir en el intento (1/n)

Como desarrolladores, muchas veces nos hemos enfrentado a la necesidad de manipular archivos en formato excel.

Una forma, es manipular dichos archivos a través de la biliboteca de interoperabilidad Microsoft.Office.Interop.Excel.dll. Sin embargo, esto requiere que tengamos instalados ensamblados especiales de acuerdo a la compilación que hayamos realizado, lo cual podría provocar el clásico error El proveedor ‘Microsoft.ACE.OLEDB.12.0’ no está registrado en el equipo local. En esta entrada, veremos una forma mucho más sencilla de manipular archivos de Excel de una forma nativa y sin necesidad incluso de tener instalado Excel en la máquina de los clientes.

Overview

Los archivos de Office de las versiones actuales de Office, están basados en OpenXML, cuya definición en Wikipedia es:

Office Open XML (también llamado OOXML u OpenXML) es un formato de archivo abierto y estándar cuyas extensiones más comunes son .docx, .xlsx y .pptx. Se le utiliza para representar y almacenar hojas de cálculo, gráficas, presentaciones y documentos de texto. Un archivo Office Open XML contiene principalmente datos basados en el lenguaje de marcado XML, comprimidos en un contenedor .zip específico.

Es decir, que si contamos con un archivo con extensión .xlsx, basta con cambiarle dicha extensión por una .zip, para poder descomprimirlo y ver en su interior el contenido del archivo tal como en la siguiente imágen:

Screen Shot 03-04-16 at 12.33 PM

Screen Shot 03-04-16 at 12.42 PM

Podemos darnos cuenta entonces, que un archivo de Excel no es más que un conjunto de archivos xml que podemos manipular a nuestro antojo para llevar a cabo distintas operaciones.

Trabajando con archivos de Excel

Para no reinventar la rueda, hoy en día existen diferentes alternativas para abrir documentos con formato open xml. En esta publicación haremos uso de ClosedXML Basta con ir a la página oficial en CodePlex para descargar la dll que necesitemos (framework 3.5 o 4) y descomprimir el archivo .zip descargado para poder utilizar la biblioteca. Por último (Lo remarco en rojo porque es importante) debemos descargar la biblioteca DocumentFormat.OpenXml, ya sea para el framework +4.0 ó 3.5

Creando un archivo de Excel

El uso de la biblioteca (al ser orientado a objetos) resulta extremadamente sencillo. Si deseamos crear una instancia de un libro de Excel, basta con utilizar la clase XLWorkbook, el cual contiene una propiedad haciendo referencia a las hojas del libro, las que a su vez contienen referencias a las celdas.

Nuestro primer ejemplo, consistirá en crear un libro en Excel, el código para hacerlo es el siguiente:

var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Sample Sheet");
worksheet.Cell("A1").Value = "Hola mundo desde Excel!";
workbook.SaveAs("HelloWorld.xlsx");

 

Una vez ingresado el código en el manejador de eventos de un botón, tendremos un libro de Excel satisfactoriamente creado:

Screen Shot 03-04-16 at 01.02 PM

Screen Shot 03-04-16 at 01.11 PM

Screen Shot 03-04-16 at 01.11 PM 001

En la siguiente entrada, nos dedicaremos a manipular archivos de Excel existentes.

¡Hasta la próxima!

Manejar acceso a datos a través de una clase administrada (1/n) (Hyrule)

Tomando como referencia un post anterior, continúo esta serie de artículos relacionados con facilitar nuestro día a día en el desarrollo de aplicaciones.

Para propósitos de esta serie de posts, utilizaremos un repositorio en GitHub, alojado en la dirección:

https://github.com/hprez21/Hyrule

A menudo me encuentro con muchos programadores que no tienen separada su lógica para acceso a datos, inclusive en proyectos grandes y de suma importancia. Es común observar en estos proyectos, la repetición constante de código para llevar a cabo una simple ejecución de una consulta a la base de datos.

La primer clase que agregaremos en nuestra biblioteca de clases, se llama “SQLHelper”, desarrollada por Microsoft como parte de su Microsoft Data Access Application Block for .NET, el cual podemos encontrar en el respositorio de GitHub, y la cual está compuesta por más de 4,500 líneas de código.

Para poder llevar a cabo una prueba rápida de la biblioteca, agregaremos un nuevo proyecto en Visual Studio de tipo consola al que denominaremos “Hyrule.DemosData”, al cual agregaremos la referencia a Hyrule.Data:

Screen Shot 02-01-16 at 03.18 PM

Una vez hecho esto, podemos agregar la referencia en código, y utilizar la clase para ver la lista de métodos disponibles:

 

Screen Shot 02-01-16 at 03.22 PM

Otra forma de conocer qué métodos están disponibles para nuestro uso, es yéndonos al menú View –> Object Browser, donde examinando el espacio de nombres Hyrule.Data, podemos observar la lista de métodos disponibles.

Screen Shot 02-01-16 at 03.25 PM

En la próxima entrega, comenzaremos a ver la forma de utilizar de forma general, los métodos de la clase.

 

Saludos.

Diferencia entre tipo de dato float, double y decimal en C#

Todos estos tipos de dato son similares debido a que todos tienen un valor decimal, pero son diferentes en la forma en la que almacenan dicho valor. Un valor del tipo float tiene una precisión de 7 dígitos, mientras que un valor del tipo double entre 15-16 dígitos. Por otra parte, un valor del tipo decimal, tiene una precisión de 28-29 dígitos. Esto significa que debemos utilizar cada uno de ellos, de acuerdo a la situación a la que nos enfrentemos:

Decimal:

Debe ser utilizado en aplicaciones de alta precisión, como por ejemplo, las financieras, o aquellas donde se hagan cálculos que requieran suma precisión.

Double:

Puede usarse en situaciones que no requieran el uso de dinero.

Float:

Puede usarse en situaciones en las que puedan existir errores de redondeo, y requieran el uso intensivo de procesamiento, como el dibujo de gráficas o juegos.

Ejemplos de Uso:

//Decimal
decimal decimal = 12.12m;

//Flotante
float doble = 12.12f;

//Doble
double doble = 12.12d;

 

Saludos.

¿Cómo comparar el esquema entre 2 bases de datos? (3/3) [Serie–Sincronizando Esquemas e Información entre bases de datos]

En la entrada anterior, veíamos la segunda herramienta para llevar a cabo comparaciones entre esquemas de bases de datos. Hoy toca el turno a mi última recomendación, que es Visual Studio Schema Compare for SQL Server Database Projects.

Visual Studio Schema Compare for SQL Server Database Projects

Prerrequisitos:

  • Visual Studio 2013 Ultimate
  • Visual STudio 2013 Premium
  • Visual Studio Community 2013

Esta es una herramienta que viene incluida en las versiones enlistadas anteriormente. Para hacer uso de la misma, basta seleccionar la siguiente opción:

Screen Shot 03-04-15 at 09.10 PM

Posteriormente, nos saldrá una ventana en la cual, de nuevo, al igual que en las herramientas anteriores, debemos seleccionar una base de datos orígen, y una base de datos destino:

Screen Shot 03-04-15 at 09.12 PM

Si no nos aparece ninguna base de datos para seleccionar, debemos dar click sobre la opción “Select Source”, lo cual nos desplegará lo siguiente:

Screen Shot 03-04-15 at 09.13 PM

En esta ventana, te aparecerán las diferentes opciones de las cuales puedes hacer uso, en mi caso he seleccionado una conexión a una base de datos. Haremos lo mismo con la base de datos destino:

Screen Shot 03-04-15 at 09.14 PM

Por último, basta con dar click sobre el botón “Compare” para iniciar la comparación de esquemas:

Screen Shot 03-04-15 at 09.15 PM

Esto nos desplegará, los diferentes cambios encontrados entre ambas bases de datos, categorizados por el tipo de cambio que debe de hacerse:

Screen Shot 03-04-15 at 09.20 PM

En nuestro ejemplo, veremos que se debe realizar un cambio. Si nos posicionamos encima de la tabla, podremos visualizar cuál es la diferencia entre ambas tablas:

Screen Shot 03-04-15 at 09.22 PM

Veremos que existen 3 cambios que debemos aplicar si deseamos empatar el esquema de bases de datos.

  1. Cambiar el nombre a un largo de 200
  2. Cambiar el género de char(1) a entero
  3. Agregar la llave primaria [PK_Person]

En caso de que queramos que la actualización se lleve a cabo gestionada por Visual Studio, debemos seleccionar aquellas tablas u objetos que deseamos actualizar:

Screen Shot 03-04-15 at 09.25 PM

Una vez hecho esto, podremos ver el scrip que se generaría en caso de que se llevara a cabo la actualización, donde, en nuestro ejemplo, las líneas más relevantes serían las siguientes:

Screen Shot 03-04-15 at 09.27 PM

Si es lo que deseamos, simplemente debemos actualizar el esquema, dando click en el botón “Update”:

Screen Shot 03-04-15 at 09.28 PM

Con lo que obtendremos un error:

Screen Shot 03-04-15 at 09.31 PM

Esto sucede porque tenemos información en nuesta base de datos, la cual podríamos afectar. Para cuestiones de ejemplo, lo corregiremos eliminando esta sección del script:

Screen Shot 03-04-15 at 09.32 PM

Con esto, no tendremos más errores, y habremos sincronizado el esquema entre ambas bases de datos.

Screen Shot 03-04-15 at 09.33 PM

Conclusiones

En esta serie de entradas, hemos visto 3 herramientas que pueden ser de gran utilidad al momento de llevar a cabo sincronizaciones entre esquemas de bases de datos. Es tu turno decidir cuál te conviene más.

Saludos.

¿Cómo comparar el esquema entre 2 bases de datos? (2/3) [Serie–Sincronizando Esquemas e Información entre bases de datos]

En el artículo anterior, hablábamos acerca de DbComparer como herramienta para comparar esquemas entre 2 bases de datos. hoy toca el turno de OpenDbDiff.

OpenDbDiff

Hospedado en el sitio de CodePlex, este proyecto nos describe lo siguiente:

Open DBDiff es una herramienta de comparación esquema open source de bases de datos de SQL Server 2005/2008.

Se informa de las diferencias entre dos esquemas de base de datos y proporciona un script de sincronización para actualizar una base de datos de uno a otro.

Cuando ejecutamos la aplicación, veremos, al igual que DbComparer, 2 apartados para especificar una base de datos de orígen, y una base de datos destino, donde debemos especificar la información correspondiente a cada una de ellas, como en el siguiente ejemplo:

Screen Shot 03-02-15 at 07.33 PM

Una vez hecho esto, debemos dar click en el botón “Compare” para llevar a cabo la comparación:

Screen Shot 03-02-15 at 07.34 PM

lo cual nos generará un listado con las diferencias entre ambas bases de datos. Continuando con nuestra información de ejemplo, al abrir la pestaña de las tablas, veremos algo como lo siguiente:

Screen Shot 03-02-15 at 07.36 PM

donde, dependiendo el color del texto, significará alguna de las siguientes 3 opciones:

Screen Shot 03-02-15 at 07.37 PM

En nuestro ejemplo concreto, veremos debemos llevar a cabo una consulta del tipo Alter para poder dejar a la par ambas bases de datos. La aplicación nos ayudará, brindándonos el script para crear la( s ) tabla ( s ) correspondiente (s ).

Script de la tabla anterior:

Screen Shot 03-02-15 at 07.40 PM 001

Script de la tabla nueva:

Screen Shot 03-02-15 at 07.40 PM

Por último, si deseamos aplicar dichos cambios de forma automática, bastará con seleccionar el ó los ítems correspondientes, y dar click sobre “Update Item”:

Screen Shot 03-02-15 at 07.44 PM

Screen Shot 03-02-15 at 07.44 PM 001

con lo que nos saltará una advertencia:

Screen Shot 03-02-15 at 07.44 PM 002

Que básicamente nos dice, que no se podrán revertir los cambios. Al aplicar los cambios, si no hay mayor complicación, nos saldrá un mensaje diciendo que todos los cambios fueron satisfactorios:

Screen Shot 03-02-15 at 07.46 PM

Posterior a esto, se iniciará de nuevo el proceso de comparación, esta vez, mostrándonos los objetos sin ningún tipo de problema:

Screen Shot 03-02-15 at 07.47 PM

Con esto, tenemos una ayuda bastante poderosa para tener nuestras bases de datos sincronizadas.

Nos vemos en la siguiente entrada.

Saludos.

¿Cómo comparar el esquema entre 2 bases de datos? (1/3) [Serie–Sincronizando Esquemas e Información entre bases de datos]

La comparación entre esquemas de 2 bases de datos, puede ser una tarea titánica si se realiza de forma manual. Es por eso, que en esta serie de posts, indicaré cómo llevar a cabo comparaciones entre esquemas de bases de datos, comparaciones entre los datos de diferentes bases de datos, y finalmente, veremos paso a paso cómo realizar una aplicación para que podamos utilizarla en nuestros desarrollos sin depender de herramientas de terceros. Iniciemos entonces con esta serie que espero sea de su agrado, y a más de uno sirva como me ha servido a mí.

En la red existen múltiples aplicaciones, que nos prometen llevar a cabo la comparación entre bases de datos de una forma sencilla, a menudo, estas aplicaciones tienen un costo. Algunas de estas son:

Link del producto Precio
http://www.red-gate.com/products/sql-development/sql-compare/ $745.00 dólares americanos
https://www.devart.com/dbforge/sql/schemacompare/ $149.95 dólares americanos
http://www.adeptsql.com/ $240.00 dólares americanos

Es cierto que cada quien tiene el derecho de ponerle el precio a los productos que desarrolla, pero no creo conveniente comprar una licencia de alguno de estos productos, si sólo la utilizaremos una vez en un año. Es por ello, que en esta serie de posts, recomendaremos algunas herramientas que nos pueden ayudar a llevar a cabo dichas tareas de forma sencilla y sin pagar un sólo peso (Aunque si tienes oportunidad, te recomiendo realizar donaciones a este tipo de proyectos):

Requisitos previos:

Para poder reproducir lo que haremos en esta serie posts, debes ejecutar este script sobre tu servidor de bases de datos:

Script para pruebas

El contenido de dicho archivo, es el siguiente:

CREATE DATABASE BlogTestSource
GO
CREATE DATABASE BlogTestTarget
GO
USE [BlogTestSource]
GO

/****** Object:  Table [dbo].[Person]    Script Date: 25/02/2015 08:33:33 p. m. ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Person](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](100) NOT NULL,
    [Age] [int] NOT NULL,
    [Gender] [int] NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

USE [BlogTestTarget]
GO

/****** Object:  Table [dbo].[Person]    Script Date: 25/02/2015 08:33:51 p. m. ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Person](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](200) NOT NULL,
    [Age] [int] NOT NULL,
    [Gender] [char](1) NOT NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

USE [BlogTestSource]
GO
SET IDENTITY_INSERT [dbo].[Person] ON 

INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (1, N'Rick', 31, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (2, N'Sasha', 22, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (3, N'Daryl', 19, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (4, N'Glenn', 23, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (5, N'Maggie', 18, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (6, N'Carl', 10, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (7, N'Carol', 40, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (8, N'Michonne', 31, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (9, N'Eugene', 27, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (10, N'Rosita', 18, 2)
SET IDENTITY_INSERT [dbo].[Person] OFF
GO

USE [BlogTestTarget]
GO
SET IDENTITY_INSERT [dbo].[Person] ON 

INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (1, N'Rick', 31, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (2, N'Sasha', 22, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (3, N'Daryl', 19, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (4, N'Glenn', 23, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (5, N'Maggie', 18, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (6, N'Carl', 10, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (7, N'Carol', 40, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (8, N'Michonne', 31, 2)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (9, N'Eugene', 27, 1)
INSERT [dbo].[Person] ([Id], [Name], [Age], [Gender]) VALUES (10, N'Rosita', 18, 2)
SET IDENTITY_INSERT [dbo].[Person] OFF
GO

DbComparer

Eso es lo que describe el sitio web:

DBComparer es una herramienta de comparación de base de datos profesional para el análisis de las estructuras de base de datos de diferencias en Microsoft SQL Server 2008 (y 2005). Es una excelente herramienta para cualquier equipo de desarrollo de proyecto o DBA gestión de múltiples copias de la misma base de datos en un servidor SQL. Esta herramienta de comparación de base de datos tiene una interfaz limpia y directa. Resultados se presentan claramente para que usted puede ver inmediatamente las diferencias en sus bases de datos. Hará que localizar y eliminar las diferencias en su base de datos rápida y fácil.

Al realizar la primer ejecución, se nos despliega el siguiente cuadro de diálogo, donde deberemos seleccionar la base de datos de la izquierda (origen) y la base de datos de la derecha (destino), de la siguiente manera (si es que has ejecutado el script que te he puesto al inicio del post):

Screen Shot 02-25-15 at 10.21 PM

Posteriormente daremos click al botón “Compare Now”, lo que iniciará una comparación entre las bases de datos seleccionadas, mostrándonos lo siguiente:

Screen Shot 02-25-15 at 10.24 PM

Podemos ver, de manera sencilla, dónde tenemos diferencias de esquema entre ambas bases de datos, ya que es mostrado con color rojo, en este caso, es en el folder de las tablas donde tenemos conflictos, expandamos para ver lo que ocurre:

Screen Shot 02-25-15 at 10.26 PM

Si seguimos expandiendo los nodos, veremos cuáles son los campos en los que tenemos conflictos:

Screen Shot 02-25-15 at 10.28 PM

Seleccionando sobre la tabla (En este caso, dando click sobre dbo.Person), veremos diferentes secciones con información diferente, describiremos una por una:

Ventana de propiedades:

Screen Shot 02-25-15 at 10.29 PM

Nos mostrará las propiedades de cada una de las tablas en cuanto a estructura de la tabla en sí se refiere.

Ventana de diferencias:

Screen Shot 02-25-15 at 10.32 PM

Aquí podremos ver, de forma muy rápida y sencilla, las diferencias entre ambas tablas, en este ejemplo, vemos 2 líneas que contienen diferencias entre ambas bases de datos. Las diferencias son:

Línea 3: existe una diferencia en la definición de nvarchar, nuestra tabla orígen define un largo de 100, mientras que nuestra tabla destino define un largo de 200.

Línea 5: El campo es int en la tabla orígen, mientras que es un tipo char(1) en nuestra tabla destino.

Venta de diferencias por línea:

Screen Shot 02-25-15 at 10.34 PM

 

Nos permite comparar línea por línea, de acuerdo a la línea que tengamos seleccionada en la venta de diferencias. para realizar un análisis más detallado sobre cada línea, bastante útil si la consulta contiene varias líneas de código.

Desventajas de esta herramienta:

La única desventaja que encontré con esta herramienta, es que no podemos llevar a cabo la ejecución de scripts para igualar ambas bases de datos, por lo que tendremos que realizar cada una de ellas de forma manual.

En la siguiente entrega analizaremos la siguiente herramienta para comparar bases de datos,

¡Hasta entonces colegas!

¡Gánate un serial de Windows 8 u Office 2013! (Válido del 12/10/2013–31/10/2013)

Bases de la dinámica:

Descargar el juego de la tienda de aplicaciones Windows que se encuentra en la siguiente dirección:

Scooter Shooter

Una vez descargada, loguearte de alguna forma al inicio del juego(Cuenta en Clay.io o como invitado), no es necesario registrarse en Clay.io, puedes entrar como invitado, eso sí, debes poner tu nombre y apellidos para poder realizar la correspondiente verificación:

image_thumb[1]

Una vez hecho esto, pon a prueba tus habilidades y dura el mayor tiempo posible sin perder. Paso siguiente, envía tu puntuación al Leaderboard mundial:

image_thumb[3]

Por último, trata de quedar en uno de los primeros 5 lugares, ya que que a estos se les premiará con una licencia de Windows 8, o bien una licencia de Office 2013, siempre y cuando se sigan las normas establecidas.

Notas: El anuncio de los ganadores se hará por este medio; el leaderboard se reinicia a partir de hoy y sólo se dará una licencia por persona.

image_thumb[2]

Héctor Uriel Pérez Rojas

¡Gánate un serial de Windows 8 u Office 2013! (Válido del 13/08/2013–18/08/2013)

Bases de la dinámica:

Descargar el juego de la tienda de aplicaciones Windows que se encuentra en la siguiente dirección:

Aguas con la bola 2

Una vez descargada, loguearte de alguna forma al inicio del juego(Cuenta en Clay.io o como invitado), no es necesario registrarse en Clay.io, puedes entrar como invitado, eso sí, debes poner tu dirección de correo electrónico como el nombre de usuario:

image

 

Una vez hecho esto, pon a prueba tus habilidades y dura el mayor tiempo posible sin perder. Paso siguiente, envía tu puntuación al Leaderboard mundial:

 

image

 

Por último, trata de quedar en los primeros 2 lugares, ya que que a estos se les premiará con una licencia de Windows 8, o bien una licencia de Office 2013, eso siempre y cuando aparezca su dirección de correo electrónico en el leaderboard.

 

image

Héctor Uriel Pérez Rojas

Mejorando tus presentaciones y exposiciones (Parte 1)

En esta nueva serie de posts, daré tips y recomendaciones para mejorar tus presentaciones, muchas de ellas las he ido aprendiendo a través del tiempo, formando así parte de mi experiencia como expositor e impartidor de sesiones de entrenamiento, sin más preámbulo, iniciemos.

Tip 1. Usa la Lupa que incorpora Windows 7 (Magnifier)

¿Cuántas veces no ha pasado, que teniendo una diapositiva expuesta en el proyecto, el público de atrás no alcanza a ver lo que está escrito en la misma?

Esto es un problema común, que veo muy a menudo con gente que no está acostumbrada a exponer, aquellos expositores con experiencia evita poner este tipo de cosas en sus diapositivas, sin embargo, si llegas a necesitar hacer zoom en un lugar en específico, sólo basta presionar la tecla Windows más la tecla +:

image

Demostración:

Bien, veamos un ejemplo del uso de la lupa, supongamos que debemos exponer un tema de desarrollo de software, mostrando algo de código, una presentación de ejemplo se vería algo así:

image

Si alguien sentado en la parte de atrás quisiera leer o copiar el ejemplo de la lámina, simplemente se sentiría frustrado al no poder leer todo de una manera rápida y sencilla, aplicaremos la lupa ahora:

image

Como podemos observar, el resultado es simplemente increíble =)

Nos vemos en la siguiente entrega Guiño

 

Salu2

Héctor Uriel Pérez Rojas

¿Necesitas íconos para usar en tus proyectos de una manera rápida, sencilla y personalizable?

 

A menudo, ocurre que debemos utilizar íconos a nuestras aplicaciones para darles ese toque especial de UI que es necesario en muchas aplicaciones. Sin embargo, encontrar dichos íconos es a veces desgastante y quita mucho tiempo que podríamos utilizar para otras cosas.

Hoy vengo a presentarles una herramienta que me ha parecido muy buena, se llama Syncfusion Metro 1

image

Aquí tienen un video de las características principales de la herramienta:

Syncfusion Metro Studio

Cabe destacar que dentro del mismo sitio, hay más cosas disponibles totalmente gratis, como un libro para aprender a programar con jQuery:

Por último, cabe destacar que la herramienta está por tiempo limitado, ¡¡totalmente gratuita, de un precio normal de $499 dólares!!

Link: Syncfusion Metro 1

Salu2

Héctor Uriel Pérez Rojas

Concurso: Descarga VS 11 BETA, Envíanos tu Captura de Pantalla y Gana (20/04/2012 al 06/05/2012

Premios :

  • 1er. Lugar. Licencia original de Windows 7 Ultimate
  • 2º. Lugar. Licencia original de Visual Studio 2010 Ultimate
  • 3er. Lugar. Licencia original de Office Professional Plus 2010.

Para participar debes hacer lo siguiente:

· Realizar la descarga de VS BETA 11, y hacer una captura de pantalla al concluir el proceso de tu descarga. (En la captura debe poder apreciarse la hora de la descarga). Ejemplo:

image

Enlace de descarga:
http://www.microsoft.com/visualstudio/11/es-es/downloads#vs

(Son válidas las descargas de VS Professional, Premium y Ultimate).

· Enviar la captura de pantalla a las siguientes direcciones

dpelatam@hotmail.com

gs_alfaro@hotmail.com

· En el asunto debes escribir lo siguiente : VS11BETA – Geovanni Simuta Alfaro

· En el contenido del mail envía la siguiente información
-Tu nombre completo.
-Nombre de tu Escuela
-Ciclo

(Los datos anteriores nos servirán para ponernos en contacto contigo).
Todos los correos recibidos serán almacenados, para que el día 6 de mayo se haga un sorteo entre las personas participantes y se obtenga a los 3 ganadores.
La Fecha limite de envío de la Captura de pantalla y los datos es a las 23:59 hrs del Día Domingo 6 de Mayo.

Fecha del Concurso: Del 20 de Abril al 6 de Mayo del 2012

El 7 de Mayo después de realizar el sorteo nos pondremos en contacto con los ganadores y publicaremos los resultados por este mismo medio.
NOTA: Las licencias pueden ser elegidas dependiendo la arquitectura del equipo de los ganadores, X86 o X64 según deseen. Cualquier duda sobre el concurso pueden enviar un mail a gs_alfaro@hotmail.com

ESPERAMOS SU PARTICIPACION….!

Instalando Windows 8 Consumer Preview en VHD(Virtual Hard Disk), sin máquinas virtuales y sin necesidad de particionar el disco

Introducción

Windows 8, como bien sabemos, será el próximo sistema operativo de Microsoft, contando con una interfaz diferente a lo que estamos acostumbrados a ver en sus versiones anteriores. Pues bien, esta guía, es para poder instalar la versión Consumero Preview disponible en el sitio oficial.

La ventaja de este método, sobre el uso de virtualización a través de máquinas virtuales, es que sólo el disco duro es virtualizado, mientras que los demás dispositivos no. Esto como te imaginarás, te da un mayor realismo sobre cómo se comportará tu máquina una vez que Windows 8 sea lanzado.

Dos alternativas

Existen en la red muchos tutoriales sobre cómo crear discos duros virtuales al estilo de Scott Hanselman en su artículo Guide to Installing and Booting Windows 8 Developer Preview off a VHD, expone varias formas para instalar un disco duro virtual, las cuales pueden ser dividas en dos formas:

a) Se hace una configuración de un nuevo disco virtual y luego se instala el sistema operativo sobre este. En este proceso, se requiere la creación de una memoria o dvd booteables creados a partir de una imagen .iso de Windows 8, dándote la misma experiencia de una instalación  en una máquina recién formateada. (Este camino es el que Scott sigue en el artículo).

b) Los otros métodos crean el disco duro virtual completo sin la necesidad de haceer un booteo de la unidad de instalación y siguiendo los pasos típicos. Este proceso se conoce como “sysprepping” y crea un sistema “casi terminado” en el disco duro virtual. Cuando se reinicias la máquina una vez ejecutado este método, tienes una experiencia similar a cuando compras una máquina OEM con unos pasos mínimos para ajustar la configuración.

Advertencia

Ante todo recuerda que esta versión de Windows es una versión Consumer Preview, es decir, aún falta algún tiempo antes de que alcance un grado de madurez final, por lo que no puedo garantizarte que funcione de forma correcta en tu máquina como en la mía, además, debes tener mucho cuidado al seguir estos pasos, ya que podrías provocar comportamientos no deseados al no ejecutar los pasos correctamente.

¿Qué necesitamos?

  • Imagen o disco de Windows 8 Consumer Preview, ya sea una versión de 32 ó 64 bits, la cual puedes descargar desde:

              .iso de Windows 8 Consumer Preview

  • Script alojado en la galería de MSDN:

              Script Necesario

 

Sección A: Creando el disco duro virtual.

Lo primero que debemos hacer, es entrar a la administración de discos duros, esto se hace, dando click con el botón derecho sobre Equipo –> Administrar

image

Esto nos desplegará la consola de Administración de equipos, nos iremos a  la sección de almacenamiento –> Administración de discos

 

image

 

Esto nos mostrará los discos  instalados en nuestro equipo:

 

image

 

Ahora, debemos crear un nuevo Disco Duro Virtual:

image

 

En este paso, debemos poner la ruta donde se creará el nuevo disco virtual, en mi caso será C:\W8.vhd, y debemos selccionar qué tipo de formato tendrá nuestro disco duro virtual: Expansión dinámica(El espacio va aumentando conforme se va utilizando), ó Tamaño Fijo (Se aparta todo el espacio de una vez), y el espacio en nuestro disco duro que le asignaremos, en mi caso,  utilizaré Expansión dinámica y un tamaño de 100 GB, a continuación, damos click en Aceptar:

image

 

Una vez creado nuestro disco duro virtual, notaremos algo así:

image

El disco duro deberemos inicializarlo, damos click sobre el disco, y seleccionamos “Inicializar Disco”

image

Con esto, saltará un menú, el cual debemos dejar con un estilo MBR, como se muestra a continuación, posterior a esto damos click en Aceptar:

image

Con esto, tendremos nuestro disco inicializado, falta crear un nuevo volúmen, esto lo haremos, dando click derecho sobre el disco, y damos click en “Nuevo volúmen simple”:

image

Nos saldrá un asistente:

image

Dejaremos la asignación de espacio tal cual:

image

Dejaremos la letra asignada por el asistente:

image

En el siguiente paso, asignaremos una etiqueta al volúmen, en mi caso le pondré Windows 8 CP:

image

y damos click en Finalizar:

image

Con esto tendremos nuestro nuevo disco virtual en el explorador de windows (puede tardar alrededor de un minuto para que aparezca):

image

 

Sección B: Instalando Windows 8 Consumer Preview.

Como primer lugar, montaremos nuestra imagen, o bien, insertaremos nuestro DVD:

image

 

Abrimos una consola de Powershell con privilegios de administrador(Click derecho –> Ejecutar como administrador):

image

Permitiremos la ejecución de scripts con el comando:

Set-ExecutionPolicy unrestricted

image

a lo que responderemos con una S:

image

Ahora, debemos ejecutar el script que hemos descargado, cuidando que no esté ubicado un lugar no permitido (por ejemplo, en raíz C:\), lo que haré será hacer un cambio de directorio, yendo a la carpeta donde se encuentra nuestro script(en mi caso la carpeta Downloads), y ejecutarlo de la siguiente forma:

.\Install-WindowsImage.ps1 -WIM F:\sources\install.wim

cuidando que la letra F, sea la letra de la unidad donde se encuentra ubicado nuestro disco de Windows:

image

 

Con esto obtendremos el índice de la unidad donde se encuentra Windows consumer Preview, ahora ejecutaremos lo siguiente:

.\Install-WindowsImage.ps1 –WIM F:\Sources\Install.wim –Apply –Index 1 –Destination G:\

Donde F es la unidad donde se encuentra nuestro disco de instalación, G es la unidad de la partición recién creada y 1 es el índice que hemos obtenido anteriormente. Con el comando anterior iniciaremos la instalación:

 

image

Este proceso es el mas tardado, todo dependerá de la capacidad de la máquina en la que nos encontremos, cuando termine la instalación, aparecerá algo como lo siguiente:

image

Finalmente, debemos colocar nuestra partición como booteable, esto lo hacemos abriendo una consola con derechos de Administrador, y ejecutando el siguiente comando:

bcdboot.exe G:\Windows

donde G, es la unidad que creaste como disco duro virtual.

image

 

Al reiniciar el equipo, deberías ver el menú para seleccionar qué sistema operativo deseas utilizar:

New Windows 8 Boot Manager?

P. D. En mi caso, tuve que buscar una alternativa para instalar el sistema operativo diferente a la de Scott, debido a que la consola no me reconocía los comandos de create vdisk… y attach vdisk…., además, es un método donde puedes estar instalando el sistema operativo mientras realizas otras tareas.

Salu2

Héctor Uriel Pérez Rojas

"Introduction to Databases" free Standford course

A bold experiment in distributed education, "Introduction to Databases" is being offered free and online to students worldwide, October 10 – December 12, 2011. Students have access to lecture videos, are given assignments and exams, receive regular feedback on progress, and participate in a discussion forum. Those who successfully complete the course will receive a statement of accomplishment. Taught by Professor Jennifer Widom, the curriculum draws from Stanford’s popular Introduction to Databases course. A high speed internet connection is recommended as the course content is based on videos and online exercises

 

image

¡Hay que aprovechar! Guiño

 

Salu2

Héctor Uriel Pérez Rojas

Creando una Biblioteca de Utilidades (Parte 1): Creando nuestro proyecto

¡Hola a todos! Tengo que admitir, que cuando uno empieza a programar, comete sin fin de errores, uno de los más cometidos, es el de no reutilizar el código que ya se ha escrito en proyectos anteriores.

En esta serie de entradas, escribiré acerca de cómo tener un set de clases y métodos, que podremos utilizar y reutilizar a lo largo de nuestros proyectos, algunas piezas de código son mi creación, algunas otras debo admitir no son creación mía (siempre que pase esto, haré la referencia debida al autor); y por creación de set de clases, no me refiero únicamente a clases que tendrán métodos que nos ayudarán, sino también a controles personalizados, que extiendan la funcionalidad de controles ya existentes de .Net. Todo esto lo veremos a través de estas entradas, que si bien, tengo bastante código por compartir, me gustaría que me dieran su opinión, si hay piezas de código que quieran que examinemos, con gusto también lo haremos 🙂

Empecemos entonces nuestro viaje.

En primer lugar, crearemos un nuevo proyecto, del tipo Biblioteca de Clases, en mi caso lo haré en C#. Sin embargo, quiero destacar que la dll que se generará a través de este proyecto, funcionará en nuestros proyectos tanto de C# como de VB. En  mi caso lo nombraré “Utilidades”

image

 

Esto nos creará un archivo llamado Class1.cs. Lo eliminemos para empezar desde 0.

image

Bien, ya que tenemos listo esto, debemos tener una forma de organizar nuestras clases ¿verdad? Esto lo haremos a través de los llamados namespaces, en la próxima entrega hablaremos más de ellos =).

P.D. Para tener una lectura más amena de estos posts, recomiendo el visor modo Lectura de Safari, está increíble! y hace la lectura mas sencilla:

image

Salu2!

Héctor Uriel Pérez Rojas

Creando una biblioteca de Utilidades (Intro)

¡Hola amigos y amigas! Gusto en saludarles =), ya tenía rato que no pasaba por aquí para escribir algo técnico, pero a veces el tiempo falta Lengua fuera.

En esta ocasión, iniciaré una serie de posts para crear un set de clases que podrán reutilizar para sus proyectos. Esta serie irá en aumento, si alguien tiene algo que quiera compartir, algún tip, alguna pieza de código que podamos agregar a dicha biblioteca, bienvenido sea =).

Así que en esta semana, la primera clase o método para nuestra biblioteca, no desesperéis =D.

P.D. He agregado mi gamer tag de xbox live, por si alguien quiere echar una retita Lengua fuera.

 

Salu2

Héctor Uriel Pérez Rojas

Increíbles aplicaciones WPF # 2

Hola! ¿Qué tal a todos?  Espero que estén excelente Sonrisa, bueno, pues regresamos al mundo del blogueo, esta vez, siguiendo con la línea de Increíbles aplicaciones WPF.

La aplicación en cuestión se llama Books.Show. Esta, es una aplicación de lectura, de ejemplo basada en WPF que está enfocada a Windows 7. Es un lector funcional totalmente que permite la lectura de alrededor de 40 libros de habla inglesa inluyentes de todos los tiempos. Soporta Touch para ir recorriendo las páginas, también encontrarás que integra con la Taskbar. Además, se incluye el código fuente de la aplicación de ejemplo, el cual, incluye el código completo de la aplicación para escribir aplicaciones con características cool de Windows 7.

 

Sin mas por decir. algunas capturas de la aplicación:

image

 

image

 

image

image

 

image

 

Como ven, una aplicación rica visualmente, y lo mejor de todo, como ya dije anteriormente, con el código fuente disponible para descargar Sonrisa

 

El link de la aplicación:

http://code.msdn.microsoft.com/Books

 

Salu2.

Héctor Uriel Pérez Rojas

3 Concurso del blog: ¡Gánate una licencia de Microsoft Office Profesional 2010!{Terminado}

Estamos de fiesta con el lanzamiento de Office 2010, así que me he animado a realizar otro concurso, con el que son 2 ya los que están en curso.

La temática es esta: Mi amiga Karinthia, hace algún tiempo encontró una foto de una chica que se parece bastante a ella, sin embargo, desconoce la identidad de dicha chica. Pongo a continuación una foto de ella, y una foto de la chica que se parece a ella.

Mi amiga Karinthia:

image

La chica que se parece a Karinthia 

Foto_concurso1

Fue la foto más cercana en ángulo que encontré je je, la mecánica es esta:

La identidad de la chica se puede descubrir utilizando algunas herramientas disponibles en la web, así que, el primero que me diga la identidad de la chica  de la foto en blanco y negro, será el ganador de la licencia de Office 2010 profesional. Es posible descubrirla, puesto que yo ya lo he hecho 😉

Salu2

Héctor Uriel Pérez Rojas

¡Gánate un serial de Windows 7 Home Premium + serial de Office 2010 Profesional originales!{28/04/10 al 05/04/10}

  +  

Así es, este concurso es realmente sencillo, pero lleva algo de tiempo, además, cualquiera puede participar.

Bien, por curiosidad, en días pasados me lancé a buscar algún documento donde estuvieran todas las fórmulas de excel, con descripción y ejemplo, pero no encontré ninguno.

La mecánica es esta:

Requiero un documento Excel con todas las fórmulas de excel en español, así como el siguiente ejemplo:

http://cid-2c11b62be5eb284d.skydrive.live.com/self.aspx/P%c3%bablico/formulas.xlsx

 

Para que el trabajo no sea en vano, puedes licenciarlo bajo Creative Commons, y ser el primero en publicar un documento de esta índole.

Este concurso tiene una duración de una semana, y deberán mandar el archivo a la dirección unach@hotmail.com.

Quiero destacar que entregaré seriales a todos los que envíen su archivo de solución, siempre y cuando, no haya sido copiado de algún otro sitio, o sea duplicado, obviamente que también esté completo. El jurado decidirá 🙂

Salu2

Héctor Uriel Pérez Rojas

Microsoft Office 2010 alcanza su estado RTM

Así es señores, Office 2010 al fin llega a nosotros en su estado RTM, el día de hoy ha sido publicada la versión profesional para los suscriptores Technet  y MSDN:

image

En lo personal lo he bajado y me ha gustado mucho. Aquí les dejo algunas capturas de este nuevo paquete ofimático de la mano de los chicos de Redmond:

Microsoft Word 2010:

image

Aquí una captura de Power Point 2010, con uno de los nuevos diseños:

image

Excel aplicando un formato de tabla nuevo:

image

Una de las características que me ha gustado de este nuevo Office, es la posibilidad de ver exactamente cómo lucirá tu documento cuando sea impreso:

image

Otra característica nueva, es la posibilidad de publicar tus documentos, directamente en tu Skydrive:

image

De verdad, las características nuevas son bastantes, para obtener mayor información, te recomiendo ir al sitio http://office2010.microsoft.com/es-mx/microsoft-office-2010-FX100996036.aspx , donde tendrás acceso a las novedades en español de esta versión.

Tal vez me anime luego de realizar un concurso para sortear una licencia para esta suite, veremos q tal marchan las cosas je je, alguna sugerencia para esto?

Como comentario final, sigo trabajando en la serie de posts sobre creación de instaladores en Visual Studio, así que espérenlos con calma 😉

Salu2

Héctor Uriel Pérez Rojas

Tips para programar Orientado a Objetos con C#.- Tip #3: Ten un constructor central

Hola, tercera tip para programar Orientado a Objetos en C#, cualquier duda o comentario, háganmelo saber 🙂

Contexto:

Es muy común en las aplicaciones .Net, tener clases que tengan constructores de diversas firmas, es decir, que puedan ser llamadas de distintas formas. Un ejemplo, tomado de las clases del .NET Framework, es la clase SqlCommand, la cual tiene varios parámetros con los cuales puede ser inicializado:

image

Como puedes ver, cuando trabajas con esta clase, puedes llamar a la misma pasándole ningún parámetro, una cadena como parámetro, o bien un cadena y un objeto del tipo SqlConnection, para los que no lo sepan, a esto se le llama overloading (o sobrecarga en español), y nos sirve para tener un mismo método con el mismo nombre, pero que reciba diferentes parámetros.

Hagamos nosotros un ejemplo de esto, creemos una nueva clase, con 3 propiedades, y 1 constructor, que será básicamente lo que hemos visto en el tip # 2:

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public decimal Efectivo { get; set; }

   6:  

   7:     public Cliente(string _nombre, int _edad, decimal _efectivo)

   8:     {

   9:         this.Nombre = _nombre;

  10:         this.Edad = _edad;

  11:         this.Efectivo = _efectivo;

  12:     }

  13: }

A esta clase, le agregaremos un nuevo constructor, el cual tendrá una sobrecarga de 2 parámetros, y en el cual, inicializaremos el valor efectivo a 0:

 

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public decimal Efectivo { get; set; }

   6:  

   7:     public Cliente(string _nombre, int _edad, decimal _efectivo)

   8:     {

   9:         this.Nombre = _nombre;

  10:         this.Edad = _edad;

  11:         this.Efectivo = _efectivo;

  12:     }

  13:  

  14:     public Cliente(string _nombre, int _edad)

  15:     {

  16:         this.Nombre = _nombre;

  17:         this.Edad = _edad;

  18:         this.Efectivo = 0.00M;

  19:     }

  20: }

¿Y si tuviéramos otro constructor que no recibiera parámetros y quisiéramos inicializar todo a 0? ¿Qué tal otro constructor que solo reciba un parámetro? Y si tuvieras un constructor que tuviera 10 parámetros y tuviéramos que inicializar cada propiedad mediante la asignación de estos parámetros? Tendríamos que empezar a copiar y a pegar el código de cada constructor. Se dice que cuando se empieza a repetir nuestro código, algo está mal.

Mucho lío ¿No?

Solución:

Crear un constructor central, que haga todo el trabajo, y que sea solamente llamado en los constructores que deriven de él.

Así es, en nuestro ejemplo, tomaremos como constructor base el primer constructor con 3 parámetros, y lo único que haremos, será usarlo en nuestro segundo constructor de la siguiente manera:

   1: public Cliente(string _nombre, int _edad) 

   2:             : this(_nombre, _edad, 0.00M)

Esa es la manera de crear constructores que usen a uno principal. Para que veas que tanto se simplifica el código, aquí dejo el código para crear los constructores con ninguno, uno, dos y tres parámetros.

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public decimal Efectivo { get; set; }

   6:  

   7:     public Cliente(string _nombre, int _edad, decimal _efectivo)

   8:     {

   9:         this.Nombre = _nombre;

  10:         this.Edad = _edad;

  11:         this.Efectivo = _efectivo;

  12:     }

  13:     

  14:     public Cliente(string _nombre, int _edad) 

  15:         : this(_nombre, _edad, 0.00M)

  16:     {

  17:     }

  18:     public Cliente(string _nombre)

  19:         : this(_nombre, 18, 0.00M)

  20:     {

  21:     }

  22:     public Cliente()

  23:         : this("Héctor", 18, 0.00M)

  24:     {

  25:     }

  26: }

Ahora sí, tenemos disponibles diferentes inicializaciones para nuestra clase:

image

Nada de copiar y pegar. Cool eh? 🙂

Link de la solución: Tip3.zip

Salu2

Héctor Uriel Pérez Rojas

Convertir Números a Letras

He agregado a la sección utilidades, una clase llamada Conversiones, que básicamente lo que hace es convertir números a letras. Veremos su funcionamiento.

En primer lugar, lo que tienes que hacer es agregar la clase la cual puedes descargar de aquí, de la siguiente manera (Lo haré como demostración en una aplicación Windows Forms):

image

imagePara la demostración, como escenario, supondré que tengo una aplicación que requiere convertir una cantidad de dinero en texto, para esto, he agregado un textbox, donde ingresaremos la cantidad que queramos convertir, y un label, que será donde se muestre el texto convertido:

image

Sobre el código, he usado el evento TextChanged para convertir la cantidad en números, a la cantidad en letras:

   1: private void txbCantidad_TextChanged(object sender, EventArgs e)

   2: {

   3:     string cantidad = txbCantidad.Text;

   4:     string newcantidad = cantidad.Remove(0, 1);

   5:     lblCantidadLetras.Text = "Son: " 

   6:          + Conversiones.NumeroALetras(newcantidad) + " M.N.";

   7: }

Ahora, cuando empezamos a escribir, automáticamente nos convierte a letras la cantidad:

image

Quiero aclarar que el código de la clase no es mío, si alguien conoce al autor de dicha clase, hágamelo saber para darle su respectivo crédito 🙂

Salu2

Clase: NumeroALetras.zip

Héctor Uriel Pérez Rojas

Tips para programar Orientado a Objetos con C#.- Tip #2: Crea y Usa Constructores

image

 

Segundo Tip para programar Orientado a Objetos con C#, espero que a mas de uno le sirva 🙂

Contexto:

En el ejemplo del tip # 1, hemos creado una clase Cliente, el cual tiene 3 propiedades (Nombre, Edad y Cuenta). Cuando hemos hecho uso de esta clase, ha sido de la siguiente forma:

   1: static void Main(string[] args)

   2: {

   3:     Cliente cliente = new Cliente();

   4:     cliente.Nombre = "Héctor";

   5:     cliente.Edad = 23;

   6:     cliente.Cuenta = 22312;

   7:     System.Console.WriteLine(cliente);

   8: }

Como podemos ver, tenemos que inicializar explícitamente cada una de las propiedades (cliente.Nombre=”Héctor; ….).

Imagina que tienes que crear una lista de Clientes, e inicializarla desde el inicio, una posible solución sería esta:

   1: public List<Cliente> RellenarLista()

   2: {

   3:     List<Cliente> lista = new List<Cliente>();

   4:  

   5:     Cliente cliente1 = new Cliente();

   6:     cliente1.Nombre = "Héctor";

   7:     cliente1.Edad = 23;

   8:     cliente1.Cuenta = 1111;

   9:     lista.Add(cliente1);

  10:  

  11:     Cliente cliente2 = new Cliente();

  12:     cliente2.Nombre = "Vianey";

  13:     cliente2.Edad = 23;

  14:     cliente2.Cuenta = 1111;

  15:     lista.Add(cliente2);

  16:  

  17:     Cliente cliente3 = new Cliente();

  18:     cliente3.Nombre = "Anahí";

  19:     cliente3.Edad = 23;

  20:     cliente3.Cuenta = 1111;

  21:     lista.Add(cliente3);

  22:  

  23:     return lista;

  24: }

Ahora imagina, si fueran decenas de clientes los que tuvieras que inicializar, esto se vuelve cada vez mas complicado, con la sintaxis que hemos estado utilizando.

Solución:

El tip de este día es, crear constructores para inicializar los valores de las propiedades una vez creada la clase. ¿Cómo se hace esto?

A través de un constructor. Un constructor es un método que se ejecutará cuando la clase sea instanciada. Si no está declarado uno por nosotros, el .NET  Framework creará uno por nosotros.

Primero debemos modificar nuestra clase Clientes, creando un constructor. Un constructor tiene la forma:

   1: Class Cliente

   2: {

   3:     public Cliente()

   4:     {

   5:     }

   6: }

Como puedes ver, es parecido a un método, toma el mismo nombre que la clase, y no tiene ningún tipo de retorno. Este constructor será llamado cuando se utilice la palabra new.

Para nuestro ejemplo, debemos modificar nuestro constructor, de tal forma que podamos inicializar nuestras propiedades (Nombre, Edad y Cuenta), una vez que sea creada la instancia de la clase. Esto lo logramos de la siguiente manera:

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public int Cuenta { get; set; }

   6:  

   7:     public Cliente(string _nombre, int _edad, int _cuenta)

   8:     {

   9:         this.Nombre = _nombre;

  10:         this.Edad = _edad;

  11:         this.Cuenta = _cuenta;

  12:     }

  13: }

Ahora bien, cuando queramos crear una nueva instancia de Cliente, se nos pedirá que le pasemos los parámetros solicitados por el constructor que hemos creado, si no, este marcará error:

image

Lo que el error nos dice, es que el constructor de Cliente, tiene 3 parámetros, y que está tratando de ser invocado, sin ninguno, por lo que nuestra inicialización quedaría:

   1: class ListaClientes

   2: {

   3:     public List<Cliente> RellenarLista()

   4:     {

   5:         List<Cliente> lista = new List<Cliente>();

   6:  

   7:         Cliente cliente1 = new Cliente("Héctor", 23, 1111);

   8:         lista.Add(cliente1);

   9:  

  10:         Cliente cliente2 = new Cliente("Vianey", 21, 2342);

  11:         lista.Add(cliente2);

  12:  

  13:         Cliente cliente3 = new Cliente("Anahí", 22, 8232);

  14:         lista.Add(cliente3);

  15:  

  16:         return lista;

  17:     }

  18: }

Como vemos, se ha simplificado muchísimo el código, haciéndolo mas fácil de leer, y de escribir. Cualquier duda o comentario, no duden en escribirlo 🙂

Link del ejemplo: Tip2.zip

Salu2

Héctor Uriel Pérez Rojas

Tips para programar Orientado a Objetos con C#.- Tip #1: Override ToString()

image

 

Hola! ¿Qué tal? Espero que todos anden bien 😉 En esta nueva colección de posts, mencionaré algunos tips que pueden ayudar a mas de uno, a sacar el mayor provecho mientras desarrolla en una programación Orientada  a Objetos. Espero que les gusten, como siempre, comentarios, preguntas son recibidos, así que empezamos.

Contexto:

Muchas veces, cuando somos nuevos programando, cometemos el error de trabajar con nuestras clases sin sobreescribir el método ToString que viene por defecto en la clase, a qué me refiero con esto? Pues a esto:

Supongamos que tenemos una clase Cliente, con la siguiente estructura:

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public int Cuenta { get; set; }

   6: }

Para probarla, he creado una solución de tipo consola, sobre la cual creo una nueva instancia de la clase, le asigno vales a sus propiedades, y posteriormente la mando a llamar para su impresión a través del método WriteLine de la Consola:

   1: static void Main(string[] args)

   2: {

   3:     Cliente cliente = new Cliente();

   4:     cliente.Nombre = "Héctor";

   5:     cliente.Edad = 23;

   6:     cliente.Cuenta = 22312;

   7:     System.Console.WriteLine(cliente);

   8: }

Esto, nos tira el siguiente resultado:

image

Solución:

Ok, vamos con el tip, sobreescribir el método ToString que viene por defecto en cada clase, para especificar qué queremos imprimir cuando ésta sea llamada, lo único que tenemos que hacer, es agregar la siguiente sintaxis a nuestra clase:

   1: public override string ToString(){}

Con lo que, específicamente nuestra clase quedaría:

   1: class Cliente

   2: {

   3:     public string Nombre { get; set; }

   4:     public int Edad { get; set; }

   5:     public int Cuenta { get; set; }

   6:  

   7:     public override string ToString()

   8:     {

   9:         return "Mi nombre es: " + Nombre

  10:             + " y tengo: " + Edad

  11:             + "y mi cuenta ficticia es: " + Cuenta;

  12:     }

Ahora, volvemos a llamar a nuestra clase desde nuestra aplicación de consola, con lo que nos retorna:

image

Ejemplo práctico:

Ahora bien, para que no se quede todo en una aplicación de consola, para probar esto mismo he creado un formulario en WPF(igual pudo haber sido una aplicación Windows Forms, ASP.NET, etc):

image

Básicamente, el concepto es el mismo, introduce el usuario un nombre, su edad y su cuenta, y posteriormente es agregado a la lista de los clientes.

   1: private void btnAgregar_Click(object sender, RoutedEventArgs e)

   2: {

   3:     Cliente cliente = new Cliente();

   4:     cliente.Nombre = txbNombre.Text;

   5:     cliente.Edad = int.Parse(txbEdad.Text);

   6:     cliente.Cuenta = int.Parse(txbCuenta.Text);

   7:     lsbCuentas.Items.Add(cliente);

   8: }

Ahora bien, si esto es usado sin el método sobreescrito de nuestra clase clientes, lo que se agrega es lo siguiente:

image

mientras, que sobreescribiendo el método ToString, obtenemos:

image

Les dejo el archivo de la solución en Visual Studio:

Tip1.zip

Salu2

Héctor Uriel Pérez Rojas

El proveedor ‘Microsoft.ACE.OLEDB.12.0’ no está registrado en el equipo local.

Bueno, todo empezó debido a que enlazaba un datagridview de windows forms, a un orígen de datos de una base de datos acces, sin embargo, parecía como que si las tablas estuvieran vacías:

image

Ante tal fenómeno que no lograba resolver, decidí hacerlo a través de código puro y duro, sin embargo, cuando trataba de ejecutar la aplicación me aparecía el siguiente mensaje:

El proveedor ‘Microsoft.ACE.OLEDB.12.0’ no está registrado en el equipo local.

Solución:

Buscando entre varios foros, logré descubrir que esto se debe a que no existen drivers de office 2007 para la plataforma de 64-bits, para lo cual, debes cambiar las opciones de compilación en las propiedades del proyecto:

image

Espero que a más de 1 le ahorre tiempo.

Salu2

Héctor Uriel Pérez Rojas

Memory Test!

Hey! qué tal? ya tiene rato que no posteo, pero la verdad, esto de la graduación y titulación me ha tenido sin tiempo, en un rato libre que he tenido, he desarrollado una pequeña y sencilla aplicación para el concurso 10k MIX Challenge, es un juego sencillo, en el cual tienes que recordar el color que la máquina ha hecho brillar. Ha sido un reto para mí, ya que 10k es bastante poco, jaja, pero una labor satisfactoria al ver tu trabajo posteado 🙂

image

La aplicación en cuestión:

imagePasado el día último de inscripción de aplicaciones para el concurso, estaré discutiendo cómo he desarrollado esta pequeña aplicación, y porqué no? desarrollar una versión mas completa en WPF 🙂

Vota por mi aplicación en: http://mix10k.visitmix.com/Entry/Details/222

Gracias de antemano.

Salu2

Héctor Uriel Pérez Rojas

Calendarios 2010!

Nada como empezar bien el año, para esto, en esta ocasión les traigo algunos calendarios para poder empezar a planear las actividades del próximo año :).  En total son 5, 2 archivos .xltx (Excel), 1 .dotx(Word), 1 potx (PowerPoint) y un archivo .pub (Publisher).

Algunas capturas:

image

image

 

Link: http://cid-2c11b62be5eb284d.skydrive.live.com/self.aspx/P%c3%bablico/Blog%20archives/Calendarios2010.zip

Espero que les sirvan.

Salu2

Héctor Uriel Pérez Rojas

Windows 7 – $399 Pesos para Estudiantes

Hoy, debido al lanzamiento oficial de Windows 7, Rubén me ha enviado un correo, tal vez a alguno le interese:

 

Estimados Amigos,

Sin duda alguna el día de hoy Microsoft vuelve hacer historia en la industria de tecnologías de información en el mundo.  Estoy muy contento y motivado por el impacto que estamos generando en nuestro país. Comenzando por ustedes que sin duda encontrarán en Windows, innovación, sencillez, rapidez, confiabilidad, compatibilidad, seguridad, movilidad, entretenimiento como nunca (fotos, video, música, media Room, etc..),  usar su PC más fácil que nunca!!!!, Los beneficios son para todo tipo de personas y organizaciones la mamá, el papá,  el amigo, la amiga, el niño, el estudiante, la abuelita, el abuelito, el músico, el DJ, las pymes, los colegios, las universidades, las  grandes organizaciones todos ellos encontraran grandes beneficios con Windows 7  que en conjunto con tecnologías  como Windows Live, Windows Server 2008  R2 y Microsoft Exchange 2010 podrán hablar de beneficios increíbles para el consumidor final y una nueva eficiencia en las organizaciones, como reducir costos, aumentar productividad y generar innovación.

Más allá de un lanzamiento el impacto que estamos generando en nuestro país es formidable, les comparto unos datos interesantes, en nuestro país generamos más de 90,000 empleos indirectos, en la industria de TI existen 611,000 empleos de los cuáles el 54%  de ellos están relacionados con tecnologías Microsoft, más de 300,000 empleos.  Se estima que en nuestro país la industria produzca 144,000 nuevos empleos en los próximos 3 años y se van a crear más de 1,000 compañías. La industria de SW empleara el 44% de estos nuevos empleos.  Por cada peso de ingresos que hacemos en México se generan 11.64 pesos de ingresos en nuestro ecosistema, esto es contribuir a la economía mexicana.

El compromiso que tenemos con México nunca había sido tan grande como lo es hoy,  es momento de que ELEVEMOS MEXICO,  nuestro país necesita crecer, mejorar su desarrollo económico y social, las tecnologías de información son un factor crítico en esta nueva era. Hemos construido grandes cosas estos últimos 24 años y el futuro es aún más prometedor.

¡¡¡¡¡¡Con lo anterior, quiero además compartir con ustedes que desde el día de hoy 22 de Octubre del 2009, hasta la primera semana de Enero, Windows 7 costará $399.00 (Pesos) para Estudiantes Universitarios!!!!!!

Los detalles los pueden encontrar aquí: www.windows7paraestudiantes.com.mx

Transmitan esto a sus amigos, es una gran oportunidad que jamás habíamos tenido y que ahora en México hemos logrado.

Gracias a todos por recibir mis correos y tomarse el tiempo para leer la información que les comparto.

Les envío un gran saludo y les deseo mucho éxito.

 

Salu2

 

Héctor Uriel Pérez Rojas