Как инкапсулировать MonoTouch.Диалоговое окно в контроллер вида?

я пишу контроллер представления для добавления нового элемента в мое приложение. Это идеально подходит для MonoTouch.Диалог, как это можно легко сделать с интерфейсом на основе таблицы, с полем для соответствующего свойства моего элемента.

это код, который у меня есть в настоящее время для отображения представления add item (упрощенный, но основная идея остается):

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);

пока это работает, я предпочел бы, чтобы я мог инкапсулировать детали представления в свой собственный контроллер представления, поэтому код может выглядеть так:

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

однако, я не могу понять, как реализовать это. Я думал, что логично было бы сделать подкласс DialogViewController. Однако, все конструкторы DialogViewController требуют RootElement. Чтобы получить это, вам нужно сначала создать BindingContext. Поскольку вы не можете запустить код перед вызовом базового конструктора, он не работает.

мой второй подход заключался в реализации подкласса UIViewController создать DialogViewController и добавить dialog view controller как дочерний элемент моего подкласса с помощью this.AddChildViewController(dv) и this.View.AddSubView(dv.View). Хотя это работает изначально, если у вас есть новый контроллер представления в UINavigationController и вы нажимаете элемент даты, представление даты отображается как модальное всплывающее окно, а не в иерархии навигационного контроллера. (Это имеет смысл, так как DialogViewController не NavigationController иерархия в этой конструкции).

оттуда я застрял. Я не смог найти примеров использования MonoTouch.Диалог такой в примеры тоже. Возможно ли это сделать? Или, если это не так, есть ли веская причина, почему писать такой код-плохая идея?

2 ответов


поскольку вы не можете запустить код перед вызовом базового конструктора

это не совсем верно.

это не идеально, но вы можете наследовать от DialogViewController и предоставить ему пустой RootElement например, такой:

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

позже вы можете добавить свои вещи (или установить новый RootElement) к Root свойства, например,

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

Я нашел способ сделать это, хотя это кажется немного грязным (спасибо poupou за то, что дал мне идею). Я просто установил Root в null в вызове базового конструктора, а затем сразу установил его в методе 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
}

Я не знал, что вы можете изменить корневой объект, а не просто получить к нему доступ.