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:
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.