Mes: noviembre 2012

¡OrchardHispano ha nacido!

Hoy hemos creado la comunidad hispana de Orchard. Como la mayoría sabréis Orchard es un CMS que corre encima de ASP.NET MVC 4 y está apoyado por Microsoft, de hecho, nació en Redmond.  Por ahora sólo somos unos cuantos, pero estoy seguro que pronto se unirá más gente y formaremos una gran comunidad alrededor de este excelente CMS.

Tenemos mucho trabajo por hacer, pero también tenemos mucha ilusión por este nuevo proyecto. Así que ¡únete!

La lista de correo es orchardhispano@googlegroups.com (un grupo de google) y la web www.orchardhispano.com

[MonoTouch. How to.. Usar TableViewController II CustomCell]

En mi última entrada vimos cómo crear un TableViewController para mostrar nuestros datos en forma de lista, y como plantilla para mostrar los datos elegimos la que viene por defecto. Hoy vamos a ver cómo crear nuestra propia plantilla.

Partimos del proyecto que habíamos creado en la serie anterior “ProbandoTableViewController” y lo primero que haremos será añadir una nueva vista a nuestro proyecto. Por tanto, añadimos iPhoneView (que no iPhoneViewController). Y le asignamos el nombre CustomCell. Y lo abrimos con el XCode. Eliminamos la vista, y añadimos en su lugar un TableViewCell. Agregamos una imagen y un texto: clip_image002[4]Nos dirigimos al menú superior,con nuestro TableViewCell seleccionado, que contiene las propiedades de nuestro control y le asignamos el identificador CustomCell y el Class CustomCell:

clip_image006[4]clip_image004[4]

Ahora guardamos y volvemos a XCode. Lo que viene a continuación es algo confuso y es debido a que la versión de XCode cambió (con XCode 3 era mucho más simple). Debemos crear una clase parcial con el mismo nombre que la vista, es decir, dos ficheros uno con el nombre CustomCell.cs y el otro CustomCell.designer.cs. La clase debe heredar de UITableViewCell y además, tener un constructor con el parámetro IntPtr.

El contenido inicial de CustomCell.cs

 

   1:  using System;
   2:   
   3:  using MonoTouch.Foundation;
   4:   
   5:  using MonoTouch.UIKit;
   6:   
   7:  namespace ProbandoTableViewController
   8:   
   9:  {
  10:   
  11:  public partial class CustomCell:UITableViewCell
  12:   
  13:  {
  14:   
  15:  public CustomCell (IntPtr handle): base (handle){}
  16:   
  17:  public CustomCell(){}
  18:   
  19:  }
  20:   
  21:  }

 

El contenido inicial de CuestomCell.designer.cs

using MonoTouch.Foundation;

namespace ProbandoTableViewController

{

[Register("CustomCell")] 

public partial class CustomCell{}

}

Ahora podemos abrir el CustomView.xib con Xcode y añadir los Outlets correspondientes a la imagen y al label como hemos hecho hasta ahora: arrastrando el control, manteniendo pulsado control, hacia el editor código. Los denominamos ImageCell y LabelName, guardamos y de vuelta para MonoDevelop.

Una vez en MonoDevelop nos dirigimos a la clase que acabamos de crear (en el archivo CustomView.cs) y añadimos el método:

public void addDataToCell(UIImage image, string text)

{

this.TextLabel.Text=text;

var imagen =new UIImageView(image);

imagen.Frame = new System.Drawing.RectangleF(ImageCell.Frame.Location,ImageCell.Frame.Size);

this.ImageCell.AddSubview(imagen);

}

Finalmente, nos dirigimos a la clase que creamos en el post anterior, TableSourceMain, y sustituimos el método GetCell por:

   1:  //Retorna el objeto que vamos a mostrar por pantalla. Es decir, cada celda.
   2:   
   3:  public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
   4:   
   5:  {
   6:   
   7:  CustomCell cell =(CustomCell) tableView.DequeueReusableCell(this._cellID);
   8:   
   9:  if(cell==null)
  10:   
  11:  cell =(CustomCell)Runtime.GetNSObject(NSBundle.MainBundle.LoadNib("CustomCell",new CustomCell(),null).ValueAt(0));
  12:   
  13:  cell.addDataToCell(UIImage.FromFile("MonoTouch.png"),_datos[indexPath.Row]);
  14:   
  15:  return cell;
  16:   
  17:  }

Hay que añadir una referencia al espacio de nombres MonoTouch.ObjCRuntime.

Ahora podemos compilar y veremos nuestra aplicación.

Nota: Para ajustar el diseño de la celda a nuestro gusto se puede hacer desde XCode configurando las propiedades, de igual modo para ajustar la tabla, sólo que en éste último caso desde el archivo TableViewControllerMain.xib.

[How to… Usar Table Controller]

[Entrada recuperada de Mono-Hispano]

En esta entrada vamos a ver cómo podemos crear un Table Controller. El Table Controller grosso modo es el equivalente a un GRID. Lo primero que debemos hacer, como viene siendo costumbre, es crear un proyecto nuevo al que denominaremos ProbandoTableController. Una vez tenemos nuestra solución, añadimos al proyecto un IphoneViewController y lo llamamos TableViewControllerMain. Vamos a TableViewControllerMain.cs y sustituimos la clase de la que deriva por UITableViewController: public partial class TableViewControllerMain : UITableViewController

A continuación, nos dirigimos al AppDelegate.cs y en el método FinishedLaunching agregamos el siguiente código:

TableViewControllerMain tvcm = new TableViewControllerMain();

window.RootViewController=tvcm;

Creo que a estas alturas no hace falta explicar este código, pero por si acaso: En la primera línea instanciamos nuestro TableViewController y en la segunda línea se lo asignamos como vista principal a nuestra ventana, recordemos que TableViewControllerMain hereda de UITableViewController y ésta a su vez de UIViewController . Abrimos el TableViewController.xib y en el diseñador de Xcode borramos la vista que está creada por defecto, seleccionándola y pulsando suprimir. A continuación, vamos a la librería de objetos y arrastramos un UITableView que reemplazará a la que hemos eliminado. Por último, botón derecho sobre la vista que acabamos de agregar y arrastramos -tal y como se ve en la imagen- el círculo de New Referencing Outlet sobre File´s Owner. Esto conectará añadirá

clip_image002

la vista a nuestra tabla. Si ejecutamos ahora veremos algo así, la tabla sin contenido:

clip_image004

Vamos a añadirle contenido para ello volemos a MonoDevelop y creamos la siguiente clase:

   1:  using System;
   2:   
   3:  using System.Collections.Generic;
   4:   
   5:  using MonoTouch.Foundation;
   6:   
   7:  using MonoTouch.UIKit;
   8:   
   9:  namespace ProbandoTableViewController
  10:   
  11:  {
  12:   
  13:  //Se establece la herencia de UITableViewSource
  14:   
  15:  public class TableSourceMain: UITableViewSource
  16:   
  17:  {
  18:   
  19:  private List<string> _datos;
  20:   
  21:  private string _cellID;
  22:   
  23:  public TableSourceMain ()
  24:   
  25:  {
  26:   
  27:  this._datos = new List<string>(){"Primer elemento","Segundo elemento", "Tercer elemento"} ;
  28:   
  29:  this._cellID="CellId";
  30:   
  31:  }
  32:   
  33:  //Retorna el objeto que vamos a mostrar por pantalla. Es decir, cada celda.
  34:   
  35:  public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
  36:   
  37:  {
  38:   
  39:  UITableViewCell cell = tableView.DequeueReusableCell(this._cellID);
  40:   
  41:  if(cell==null)
  42:   
  43:  cell = new UITableViewCell(UITableViewCellStyle.Default,this._cellID);
  44:   
  45:  cell.TextLabel.Text=_datos[indexPath.Row];
  46:   
  47:  return cell;
  48:   
  49:  }
  50:   
  51:  //Debe devolver el numero de elementos que queremos mostrar.
  52:   
  53:  public override int RowsInSection (UITableView tableview, int section)
  54:   
  55:  {
  56:   
  57:  return this._datos.Count;
  58:   
  59:  }
  60:   
  61:  }
  62:   
  63:  }
  64:   

Con la ayuda de los comentarios podemos ver que hace en general la clase. Sin embargo, vamos a repasarla: La clase hereda de UITableViewSource que es el origen de datos que tomará nuestra TableViewContollerMain, más adelante veremos como asignársela. La clase que acabamos de crear tiene una simple lista de string y un cellID (que nos permitirá recuperar nuestra celda). Centrándonos en el método GetCell, lo que hacemos es llamar al método tableView.DequeueReusableCell que nos devuelve una celda que hayamos usado ya (por eso usamos el identificador) esto nos permite ser más eficientes y no crearlas una y otra vez, ya que este método devuelve null si no se ha creado. A continuación, asignamos al label que viene por defecto el texto que queremos mostrar, y devolvemos la celda. Si nos fijamos cuando creamos la celda pasamos un Style por parámetro, esto es la plantilla que utilizará nuestra celda para mostrarse. En una continuación de esta entrada (que si no queda muy larga y no es la finalidad) veremos como crear nuestras propias plantillas, sólo comentar que hay más de un estilo por defecto y que se pueden probar cambian el default por algún otro valor.

Para terminar, abrimos el TableViewControllerMain y en el método ViewDidLoad asignamos a nuestra tabla, el tableSource que acabamos de crear: this.TableView.Source = new TableSourceMain();

Una introducción a los estilos arquitectónicos

Si te interesa la arquitectura del software, hoy traigo un documento An Introduction to Software Architecture

que es una buena introducción a los distintos estilos arquitectónicos. Dejo algunos ejemplos de estilos de los que se tratan en el texto:

Pipes and Filters

Creo que el ejemplo más claro proviene del mundo de los sistemas operativos, y son los comandos de consola. Por ejemplo de UNIX. ¿Quién no ha usado alguna vez una “tubería”? 

Data Abstraction and Object-Oriented Organization

Lenguajes orientados a objetos y también no orientados a objetos, ya que se pueden construir estructuras abstractas de datos con ellos. La orientación a objetos, en el sentido de tratar a un lenguaje como orientado a objetos, “sólo” facilita el trabajo.

Event-based, Implicit Invocation

Editor de código, procesador de texto (p.e. comprobación ortográfica), GUI

Layered Systems

El ejemplo del modelo OSI que citan en el texto, es bastante bueno. Uno más enfocado al mundo de la arquitectura, es el archiconocido MVC e incluso la evolución que desarrolló el principal arquitecto de Silverlight, MVVM, el cual incluso lo combina con un enfoque de Event-based a través de interfaces.

Table Driven Interpreters

Prácticamente cualquier intérprete de un lenguaje de alto nivel.

 

 

 

 

Vici CoolStorage un ORM ligero Cross Platform para MonoTouch, WP7 y MonoDroid

Sin duda una de las tecnologías que como desarrollador han mejorado mi productividad son los ORM. Hoy vengo a hablaros de Vici.CoolStorage un ORM cross platform para MonoTouch, MonoDroid y WP7 (y seguramente W8). Podéis descargarlo desde la página del proyecto.

Voy a ilustrar un ejemplo con MonoTouch en el que tendremos una clase persona:

[MapTo("Persona")]

public class Persona : CSObject<Persona,int>{

public int Id {

get;

set;

}

public string Nombre {

get;

set;

}

public string Apellidos {

get;

set;

}

}

Este código sería válido para MonoDroid y WindowsPhone pero, puesto que en el caso de MonoTouch no se soporta Reflection.Emmit, y CoolStorage la utiliza para su funcionamiento, debemos añadir el siguiente código en los getters/Setters:

[MapTo("Persona")]

public class Persona : CSObject<Persona,int>{

public int Id {

get { return (int)GetField("Id"); }

}

public string Nombre {

get { return (string)GetField("Nombre"); }

set { SetField("Nombre",value); }

}

public string Apellidos {

get { return (string)GetField("Apellidos"); }

set { SetField("Apellidos",value); }

}

}

Una vez hemos definido la clase, debemos conectarnos a la base de datos y, sólo en caso de que no exista previamente, crearla. Para ello hemos preparado el siguiente método:

void ComprobarYCrearLaDB{

string dbNombre = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "db");

CSConfig.SetDB (dbNombre,SqliteOption.CreateIfNotExists, () => {

CSDatabase.ExecuteNonQuery (

"CREATE TABLE Persona (Id INTEGER PRIMARY KEY AUTOINCREMENT," +

"Nombre text, Apellidos text)");

//Datos de ejemplo

Persona p = new Persona(){ Nombre="Jose", Apellidos="Gónzalez"} ;

p.Save();

p = new Persona(){ Nombre="Antonio", Apellidos="Gónzalez"} ;

p.Save();

} );

}

Con CSConfig.SetDb indicamos que se cree la base de datos, y el método que se ejecutará cuando se cree. En nuestro ejemplo creamos la tabla Persona en la base de datos, para a continuación crear unos datos de prueba que guardamos gracias al método Save.

Finalmente, creamos la interfaz de usuario en el punto de entrada de la aplicación:

public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            window = new UIWindow (UIScreen.MainScreen.Bounds);


            ComprobarYCrearLaDB();
            //Se crea la interfaz de usuario

            var root = new RootElement("Personas");
            var section = new Section("Personas");
            foreach (var p in Persona.List()) {
                section.Add(new StringElement(string.Format("{0} {1}",p.Nombre,p.Apellidos)));
            }
            root.Add(section);
            var dialog = new DialogViewController(UITableViewStyle.Plain,root);
            dialog.Root=root;


            window.RootViewController = dialog;
            window.MakeKeyAndVisible ();

            return true;
        }

Como veis es muy fácil comenzar con este ligero ORM. Además aunque no lo hemos visto, soporta transacciones y relaciones.  Aquí encontrareis el fichero de código completo.

[MonoTouch How To…] Usar UITabBarViewController

[Entrada original publicada en www.mono-hispano.org]

Paralelamente a la serie MonoTouch N que quizá tiene más componente de tutorial que esta, he decidido crear una serie que muestre cómo realizar acciones concretas, aunque es muy recomendable tener unos conocimientos básicos sobre MonoTouch para llevarla a cabo.

Para comenzar la serie, nada mejor que comenzar con algo bastante práctico y útil, como es la interfaz de usuario, en concreto, con el componente TabBar. Que permite navegar entre pantallas de forma bastante fluida.

tab_bar_icons_closeup

 

En primer lugar, crearemos un nuevo proyecto en MonoDevelop File->New->Solution->MonoTouch->iPhone->Empty Project y le ponemos de nombre, ProbandoTabBar.

Lo primero que debemos hacer es dirigirnos a la clase AppDelegate y crear una variable con ámbito de clase del tipo UITabBarController la llamaremos tabBar.

Lo primero que debemos hacer es agregamos dos ViewController al proyecto que serán las pantallas entre las que navegaremos. Para ello: Botón derecho sobre el proyecto->Add->New File…-> iPhoneViewController y la denominamos MainView. Repetimos el proceso para la segunda, y la denominamos OtherView.

Una vez creadas, hacemos doble click sobre el .Xib que nos ha generado, abrirá XCode y ponemos un elemento distintivo, como puede ser un Label con un texto cualquiera.

clip_image004
Repetimos el proceso con la segunda, y volvemos a Xcode.

De vuelta en MonoDevelop, nos digirimos a la clase AppDelegate y crear una variable con ámbito de clase del tipo UITabBarController la llamaremos tabBar

Dento del método FinishedLaunching, creamos el siguiente código:

   1:  public override bool FinishedLaunching (UIApplication app, NSDictionary options)
   2:   
   3:  {
   4:   
   5:  // create a new window instance based on the screen size
   6:   
   7:  window = new UIWindow (UIScreen.MainScreen.Bounds);
   8:   
   9:  //Se instancian las pantallas:
  10:   
  11:  MainView mainView = new MainView();
  12:   
  13:  OtherView otherView = new OtherView();
  14:   
  15:  //Se establece el contenido del titulo que se mostrarテ。 en el tabBar.
  16:   
  17:  mainView.TabBarItem.Title = "MainView";
  18:   
  19:  otherView.TabBarItem.Title = "OtherView";
  20:   
  21:  //Se instancia el tabBar
  22:   
  23:  tabBar = new UITabBarController();
  24:   
  25:  //Se agregan las pantallas al tabBar
  26:   
  27:  tabBar.SetViewControllers(new UIViewController[]{mainView,otherView},false);
  28:   
  29:  //Se asigna el tabBar como vista principal
  30:   
  31:  window.RootViewController=tabBar;
  32:   
  33:  // make the window visible
  34:   
  35:  window.MakeKeyAndVisible ();
  36:   
  37:  return true;
  38:   
  39:  }

El código queda explicado por sí mismo además de por los comentarios. Compilamos:

clip_image006

 

Como último detalle quisiera comentar que para añadir una imagen en el TabBarItem se puede acceder desde cualquier instancia de UIViewController o derivadas como en nuestro caso, MainView u OtherView, a través de la propidad de la misma UIViewController.TabBarItem.Image. Otra cuestión que puede resultar útil es implementar el evento de UITabBarController ViewControllerSelected que nos permitirá acceder al ViewController seleccionado cuando cambie.

Pues esto es todo, cualquier duda no dudéis en comentarla.