I am writing a view controller for adding a new item to my app. It is a perfect fit for MonoTouch.Dialog, as it can be done easily with a table based interface, with a field per relevant property of my item.
This is the code I have currently for showing the add item view (simplified, but the core idea remains):
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);
While that works, I would prefer if I could encapsulate the details of the view into its own view controller, so the code could look like this:
UIViewController controller = new AddItemViewController();
this.NavigationController.PushViewController(controller, true);
However, I can't figure out how to implement this. I thought the logical thing to do would be to make a subclass of DialogViewController
. However, all the constructors of DialogViewController
require a RootElement
. To get that, you need to firstly create the BindingContext
. As you can't run any code before calling the base constructor, it doesn't end up working.
My second approach was to implement subclass of UIViewController
, create the DialogViewController
, and the add the dialog view controller as a child of my subclass using this.AddChildViewController(dv)
and this.View.AddSubView(dv.View)
. While this works initially, if you have the new view controller in a UINavigationController, and you click a date element, the date view appears as a modal popup rather than in the navigation controller hierarchy. (This makes sense, as the DialogViewController
isn't part of the NavigationController
hierarchy in this design).
From there I'm stuck. I couldn't find any examples of using MonoTouch.Dialog like this in the examples either. Is this possible to do? Or if it's not, is there a good reason as to why writing code like this is a bad idea?
As you can't run any code before calling the base constructor
That's not quite correct.
It's not ideal but you can inherit from DialogViewController
and provide it with an empty RootElement
instance, like this:
public class AddItemViewController : DialogViewController {
public AddItemViewController () : base (new RootElement ()) { }
}
Later you can add your things (or set a new RootElement
) to the Root
property, e.g.
void Populate ()
{
this.Root.Add (new Section () { ... });
}
I found a way to do this, although it seems a little messy (thanks poupou for giving me the idea). I just set Root to null in the base constructor call, and then set it straight away in the contructor method:
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
}
I wasn't aware you could change the Root object, not just access it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With