2012-03-20 21 views
7

Estoy escribiendo un controlador de vista para agregar un nuevo elemento a mi aplicación. Es un ajuste perfecto para MonoTouch.Dialog, ya que se puede hacer fácilmente con una interfaz basada en tablas, con un campo por propiedad relevante de mi artículo.¿Cómo se encapsula una vista MonoTouch.Dialog en un controlador de vista?

Este es el código que tengo actualmente para mostrar la vista del elemento add (simplificado, pero la idea central sigue siendo):

Item item = new Item(); 
TapHandler handler = new TapHandler(); 
BindingContext bc = new BindingContext(handler, item, "Add Item"); 
DialogViewController dv = new DialogViewController(bc.Root, true); 
this.NavigationController.PushViewController(dv, true); 

Mientras que funciona, yo preferiría si pudiera encapsular los detalles de la vista en su propio controlador de vista, por lo que el código podría tener este aspecto:

UIViewController controller = new AddItemViewController(); 
this.NavigationController.PushViewController(controller, true); 

sin embargo, no puedo encontrar la manera de implementar esto. Pensé que lo lógico sería hacer una subclase de DialogViewController. Sin embargo, todos los constructores de DialogViewController requieren un RootElement. Para obtener eso, primero debe crear el BindingContext. Como no puede ejecutar ningún código antes de llamar al constructor base, no termina funcionando.

Mi segundo enfoque fue implementar subclase de UIViewController, crear el DialogViewController, y el añadir el controlador de vista de diálogo como un hijo de mi subclase utilizando this.AddChildViewController(dv) y this.View.AddSubView(dv.View). Si bien esto funciona inicialmente, si tiene el nuevo controlador de vista en un UINavigationController y hace clic en un elemento de fecha, la vista de fecha aparece como una ventana emergente modal en lugar de en la jerarquía del controlador de navegación. (Esto tiene sentido, ya que el DialogViewController no forma parte de la jerarquía NavigationController en este diseño).

A partir de ahí estoy atascado. No pude encontrar ningún ejemplo del uso de MonoTouch.Dialog como este en los ejemplos tampoco. ¿Es posible hacer esto? O si no lo es, ¿hay alguna buena razón para escribir código como este es una mala idea?

Respuesta

3

Encontré una manera de hacer esto, aunque parece un poco complicado (gracias poupou por darme la idea). Me acaba de establecer la raíz a nulo en la llamada al constructor de base, y luego otra vez de inmediato en el método contructor:

class NewItemViewController : DialogViewController 
{ 
    private Item _item; 
    public NewItemViewController(bool pushing) : base(null, pushing) 
    { 
     _item = new Item(); 
     BindingContext bc = new BindingContext(this, _item, "Add Item"); 
     this.Root = bc.Root; 
     // more setup 
    } 
    // more methods 
} 

yo no era consciente de que podría cambiar el objeto de raíz, no sólo acceder a ella.

5

Como no se puede ejecutar ningún código antes de llamar al constructor base

Eso no es del todo correcto.

No es lo ideal, pero se puede heredar de DialogViewController y dotarla de un vacío RootElement ejemplo, así:

public class AddItemViewController : DialogViewController { 
    public AddItemViewController() : base (new RootElement()) { } 
} 

Más tarde se puede añadir sus cosas (o establecer una nueva RootElement) a la propiedad Root, p.ej

void Populate() 
{ 
    this.Root.Add (new Section() { ... }); 
} 
+0

Gracias, no pensé en usar manualmente el elemento Root en el constructor. Hice mi propia respuesta que funciona con la API de reflexión estableciendo un nuevo elemento raíz en el constructor. –

Cuestiones relacionadas