如何将MonoTouch.Dialog视图封装到视图控制器中?

7
我正在编写一个视图控制器,用于向我的应用程序中添加新项目。它非常适合使用MonoTouch.Dialog完成,因为可以轻松地使用基于表格的界面完成,每个相关属性的字段都可以显示出来。
以下是我目前用于显示添加项目视图的代码(简化了一些,但核心思想保持不变):
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,然后使用this.AddChildViewController(dv)this.View.AddSubView(dv.View)将对话框视图控制器添加为我的子类的子项。虽然最初可以工作,但如果您在UINavigationController中有新的视图控制器,并单击日期元素,则日期视图将显示为模态弹出窗口,而不是在导航控制器层次结构中(这是有道理的,因为在这种设计中,DialogViewController不是NavigationController层次结构的一部分)。
从那里开始,我陷入了困境。我在示例中也找不到使用MonoTouch.Dialog进行这样的操作的示例。这是否可能做到?如果不是,写这样的代码有什么不好的原因吗?
2个回答

5

由于在调用基本构造函数之前无法运行任何代码

这并不完全正确。

虽然不是理想的做法,但您可以从DialogViewController继承并为其提供一个空的RootElement实例,如下所示:

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

稍后您可以将您的元素(或设置一个新的RootElement)添加到Root属性中,例如。
void Populate ()
{
    this.Root.Add (new Section () { ... });
}

谢谢,我没有想到手动在构造函数中使用根元素。我自己编写了一个答案,通过在构造函数中设置一个新的根元素来使用反射API。 - David Miani

3

我找到了一种方法来实现这个,虽然看起来有点凌乱(感谢poupou给我提供灵感)。我只是在基础构造函数调用中将Root设置为null,然后立即在构造函数方法中设置它:

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
}

我不知道你可以更改根对象,而不仅仅是访问它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接