使用反射 API 创建 Xamarin.iOS 应用程序

MT.D 反射 API 允许通过由 MT.D 用来自动创建屏幕的属性来修饰类。 反射 API 提供这些类与屏幕上显示的内容之间的绑定。 尽管此 API 不提供元素 API 所提供的精细控制,但它通过基于类修饰自动生成元素层次结构来降低复杂性。

设置 MT.D

MT.D 与 Xamarin.iOS 一起分发。 若要使用它,请右键单击 Visual Studio 2017 或 Visual Studio for Mac 中 Xamarin.iOS 项目的“引用”节点,然后添加对“MonoTouch.Dialog-1”程序集的引用。 然后,根据需要在源代码中添加 using MonoTouch.Dialog 语句。

反射 API 入门

可通过以下方式轻松使用反射 API:

  1. 创建一个用 MT.D 属性修饰的类。
  2. 创建一个 BindingContext 实例,并向其传递上述类的实例。
  3. 创建一个 DialogViewController ,传递它 BindingContext’s RootElement

让我们通过一个示例来演示如何使用反射 API。 在此示例中,我们将生成一个简单的数据输入屏幕,如下所示:

在此示例中,我们将生成简单的数据输入屏幕,如下所示

创建具有 MT.D 属性的类

若要使用反射 API,首先需要一个用属性修饰的类。 MT.D 将在内部使用这些属性从元素 API 创建对象。 例如,考虑以下类定义:

public class Expense
{
    [Section("Expense Entry")]

    [Entry("Enter expense name")]
    public string Name;

    [Section("Expense Details")]

    [Caption("Description")]
    [Entry]
    public string Details;

    [Checkbox]
    public bool IsApproved = true;
}

SectionAttribute 将导致创建 UITableView 的各个部分,并使用字符串参数填充该部分的标头。 声明一个部分后,它后面的每个字段都将包含在该部分中,直到声明另一个部分。 为字段创建的用户界面元素的类型取决于字段的类型和修饰它的 MT.D 属性。

例如,Name 字段是一个 string,用 EntryAttribute 进行修饰。 这会导致将一行添加到表中,该行包含文本输入字段和指定的标题。 同样,IsApproved 字段是一个带有 CheckboxAttributebool,导致在表单元格右侧添加一个包含复选框的表行。 在本例中,MT.D 使用字段名称(自动添加空格)来创建标题,因为属性中未指定该标题。

添加 BindingContext

若要使用 Expense 类,我们需要创建 BindingContextBindingContext 是一个类,它将绑定来自属性类的数据以创建元素的层次结构。 若要创建一个层次结构,我们只需实例化此类并将属性类的实例传递给构造函数。

例如,若要添加我们使用 Expense 类中的属性声明的 UI,请在 AppDelegateFinishedLaunching 方法中包含以下代码:

var expense = new Expense ();
var bctx = new BindingContext (null, expense, "Create a task");

然后,只需将 BindingContext 添加到 DialogViewController 并将其设置为窗口的 RootViewController 即可创建 UI,如下所示:

UIWindow window;

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

    var expense = new Expense ();
    var bctx = new BindingContext (null, expense, "Create a task");
    var dvc = new DialogViewController (bctx.Root);

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

    return true;
}

现在,运行应用程序会显示上面所示的屏幕。

添加 UINavigationController

但请注意,我们传递给 BindingContext 的标题“创建任务”并未显示。 这是因为 DialogViewController 不是 UINavigatonController 的一部分。 让我们更改代码以添加 UINavigationController 作为窗口的 RootViewController,,并将 DialogViewController 添加为 UINavigationController 的根,如下所示:

nav = new UINavigationController(dvc);
window.RootViewController = nav;

现在,当我们运行应用程序时,该标题将显示在 UINavigationController’s 导航栏中,如以下屏幕截图所示:

现在,当我们运行应用程序时,标题会显示在 UINavigationControllers 导航栏中

通过包含 UINavigationController,我们现在可以利用需要导航的其他 MT.D 功能。 例如,我们可以向 Expense 类添加枚举来定义费用类别,MT.D 将自动创建一个选择屏幕。 为了进行演示,请修改 Expense 类以包含 ExpenseCategory 字段,如下所示:

public enum Category
{
    Travel,
    Lodging,
    Books
}

public class Expense
{
    …

    [Caption("Category")]
    public Category ExpenseCategory;
}

现在,运行应用程序会在该类别的表中生成一个新行,如下所示:

现在,运行应用程序会在该类别的表中生成一个新行,如下所示

选择该行会导致应用程序导航到一个新屏幕,其中包含与枚举对应的行,如下所示:

选择该行会导致应用程序导航到一个新屏幕,其中包含与枚举对应的行

总结

本文提供了反射 API 的演练。 我们演示了如何向类添加属性来控制显示的内容。 我们还讨论了如何使用 BindingContext 将数据从类绑定到创建的元素层次结构,以及如何将 MT.D 与 UINavigationController 配合使用。