使用 自适应卡片 设计器创建控件模板

Windows 组件的 UI 和交互是通过 自适应卡片 实现的。 每个小组件提供一个视觉模板,并且可以选择使用一个数据模板,这些模板均通过符合自适应卡片架构的 JSON 文档进行定义。 本文将逐步指导你完成创建简单小部件模板的步骤。

计数小组件

本文中的示例是一个简单的计数小组件,它显示整数值,并允许用户通过单击小组件用户界面中的按钮增加数值。 此示例模板使用数据绑定根据数据上下文自动更新 UI。

应用需要实现小组件提供程序来生成和更新小组件模板和/或数据,并将其传递给小组件主机。 在 Win32 应用中实现小组件提供程序一文提供了分步指南,指导如何为下面步骤中将要生成的计数小组件实现小组件提供程序。

自适应卡片设计器

自适应卡片 Designer 是一种联机交互式工具,可用于轻松生成用于自适应卡片的 JSON 模板。 使用设计器,你可以在构建小组件模板时实时查看渲染的视觉效果和数据绑定行为。 按照链接打开设计器,该设计器将用于本演练中的所有步骤。

从预设创建空模板

在页面顶部的 “选择主机应用程序” 下拉列表中,选择“组件板”。 这将把自适应卡片的容器大小设置为小组件所支持的尺寸。 请注意,小组件支持小、中、大三种尺寸。 默认模板预设的尺寸正是小型组件的合适尺寸。 如果内容超出了边界,请不要担心,因为我们会将其替换为专门设计以适应该小组件内部空间的内容。

页面底部有三个文本编辑器。 标有卡有效负载编辑器的文件包含你的小组件 UI 的 JSON 定义。 标记为 Sample Data Editor 的编辑器包含用于定义控件的可选数据上下文的 JSON。 渲染小组件时,数据上下文会动态地绑定到自适应卡片。 有关自适应卡片中的数据绑定的详细信息,请参阅自适应卡片模板语言

第三个文本编辑器标记为 示例主机数据编辑器。 请注意,此编辑器可能折叠在页面的其他两个编辑器下方。 如果是这样,请单击 +以展开编辑器。 小组件主机应用可以指定可在小组件模板中使用的主机属性,以基于当前属性值动态显示不同的内容。 小组件面板支持以下主机属性。

财产 价值 说明
host.widgetSize “小”、“中”或“大” 已固定小组件的大小。
host.hostTheme “light”(浅色)或“dark”(深色) 显示小组件板的设备当前主题。
host.isSettingsPayload 真 或 假 如果此值为 true,则用户已单击小组件上下文菜单中的“ 自定义小组件 ”按钮。 可以使用此属性值显示自定义设置 UI 元素。 这是一种替代方法,用于在不使用 IWidgetProvider2.OnCustomizationRequested 的情况下,修改小组件提供程序应用中的 JSON 有效负载。 有关详细信息,请参阅 “实现小组件自定义”。
host.isHeaderSupported 真 或 假 如果此值为 true,则支持标头自定义。 有关详细信息,请参阅 isHeaderSupported
host.isHeader 真 或 假 当此值为 true 时,表示主机正在请求专门用于渲染小组件标题的有效负载。
host.isWebSupported 真 或 假 当此值为 false 时,主机当前不支持加载小组件的 Web 内容。 发生这种情况时,网页小工具将显示由小工具提供程序提供的回退 JSON 有效负载,但此值可以用来进一步自定义小工具的内容。 有关详细信息,请参阅 Web 小组件提供程序
host.isUserContextAuthenticated 真 或 假 如果此值为 false,则唯一支持的操作是 Action.OpenUrl。 鉴于交互性限制,isUserContextAuthenticated 的值可以用于适当调整小部件内容。

页面顶部“选择主机应用”下拉列表旁边的容器大小主题下拉列表允许你设置这些属性,而无需在编辑器中手动编辑示例主机 JSON。

创建新卡片

在页面左上角,单击“ 新建卡片”。 在“ 创建 ”对话框中,选择 “空白卡片”。 现在,你应该会看到一张空白的自适应卡片。 你还将注意到示例数据编辑器中的 JSON 文档为空。

我们将创建的计数小组件非常简单,仅包含 4 个 TextBlock 元素和一个 Action.Execute 类型的操作,用于定义小组件的按钮。

添加 TextBlock 元素

从页面左侧的卡片元素窗格中,将四个 TextBlock 元素拖放到预览窗格中的空白自适应卡片上。 此时,小组件预览应如下图所示。 内容再次超出了小组件的边界,但这将在接下来的步骤中得到解决。

一张正在制作中的自适应卡片。它显示了一个包含四行文本的小组件,文本内容为“New TextBlock”。这四行文本超出了小组件的底部边框。

实现条件布局

卡片有效负载编辑器已更新,以反映我们添加的 TextBlock 元素。 将 正文 对象的 JSON 字符串替换为以下内容:

"body": [
    {
        "type": "TextBlock",
        "text": "You have clicked the button ${count} times"
    },
    {
        "type": "TextBlock",
        "text": "Rendering only if medium",
        "$when": "${$host.widgetSize==\"medium\"}"
    },
    {
        "type": "TextBlock",
        "text": "Rendering only if small",
        "$when": "${$host.widgetSize==\"small\"}"
    },
    {
        "type": "TextBlock",
        "text": "Rendering only if large",
        "$when": "${$host.widgetSize==\"large\"}"
    }
]

在自适应卡片模板语言中,$when 属性指定当关联的值评估结果为 true 时,显示其所包含的元素。 如果该值的计算结果为 false,则不显示包含元素。 在我们的示例中的 正文 元素中,将显示三个 TextBlock 元素之一,另外两个元素将隐藏,具体取决于属性的值 $host.widgetSize 。 有关自适应卡片中支持的条件的详细信息,请参阅 带有$when条件的布局

现在预览应如下图所示:

一张正在制作中的自适应卡片。它显示了一个小组件,其中包含四行文本,内容来自上一步中显示的 JSON 有效负载。与条件性隐藏元素不同,所有元素均可见,并超出了图片的底部边框。

请注意,条件语句不会反映在预览中。 这是因为设计器未模拟小组件主机的行为。 单击页面顶部的 “预览模式 ”按钮以启动模拟。 小组件预览现在如下图所示:

一张正在制作中的自适应卡片。它显示了一个包含两行文本的小组件,这些文本来自 JSON 有效负载。此时仅渲染了小尺寸对应的 TextBlock。

“容器大小 ”下拉列表中选择“中等”,请注意预览切换为仅显示中等大小的 TextBlock 。 预览中的容器也会改变大小,展示您如何利用预览来确保您的 UI 能适应每个受支持大小的小部件容器。

绑定到数据上下文

我们的示例小组件将使用名为“count”的自定义状态属性。 在当前模板中可以看到,第一个 TextBlock 的值包括变量引用 $count。 当小组件在小组件板中运行时,小组件提供程序负责组装数据有效负载并将其传递给小组件主机。 在设计时,可以使用 示例数据编辑器 对数据有效负载进行原型设计,并了解不同的值如何影响小组件的显示。 用以下 JSON 替换空白数据包。

{"count": "2"}

请注意,预览版现在会将为 count 属性指定的值插入到第一个 TextBlock 的文本中。

自适应卡片正在处理。第一行文本现在包含数据负载中的值 2。

添加按钮

下一步是向小组件添加按钮。 在小组件主机中,当用户单击按钮时,主机将向小组件提供程序发出请求。 对于此示例,组件提供商将递增计数值并返回更新的数据负载。 由于此操作需要一个微件供应商,因此无法在自适应卡片设计器(自适应卡片 Designer)中查看其行为,但仍可以使用该设计器来调整用户界面中按钮的布局。

使用 自适应卡片 时,使用 action 元素定义交互式元素。 在卡片有效负载编辑器中,将以下 JSON 代码块直接添加到 body 元素之后。 请务必在正文元素的右括号 (]) 后面添加逗号,否则设计器将报告格式设置错误。

,
"actions": [                                                      
    {                                                               
        "type": "Action.Execute",                               
        "title": "Increment",                                   
        "verb": "inc"                                           
    }                                                               
]

在此 JSON 字符串中, type 属性指定正在表示的操作的类型。 小组件仅支持“Action.Execute”操作类型。 标题包含操作按钮上显示的文本。 verb 属性是一个由应用程序定义的字符串,小组件主机会将其发送给小组件提供程序,以传达与该操作相关的意图。 小组件可以有多个操作,小组件提供程序代码将检查请求中谓词的值,以确定要执行的操作。

最后一张自适应卡片。在两行文本之后显示一个带有“增量”字样的蓝色按钮。

完整的小组件模板

以下代码列表显示 JSON 有效负载的最终版本。

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6",
    "body": [
    {
      "type": "TextBlock",
      "text": "You have clicked the button ${count} times"
    },
    {
      "type": "TextBlock",
       "text": "Rendering Only if Small",
      "$when": "${$host.widgetSize==\"small\"}"
    },
    {
      "type": "TextBlock",
      "text": "Rendering Only if Medium",
      "$when": "${$host.widgetSize==\"medium\"}"
    },
    {
      "type": "TextBlock",
      "text": "Rendering Only if Large",
      "$when": "${$host.widgetSize==\"large\"}"
    }
    ],
   "actions": [
    {
      "type": "Action.Execute",
      "title": "Increment",
      "verb": "inc"
    }
  ]
}

设置有效负载示例

以下代码列表显示了一个简单的 JSON 有效负载示例,该有效负载使用 host.isSettingsPayload 属性在用户单击“ 自定义小组件 ”按钮时显示不同的内容。

{
    "type": "AdaptiveCard",
    "body": [
    {
        "type": "Container",
        "items":[
            {
                "type": "TextBlock",
                "text": "Content payload",
                "$when": "${!$host.isSettingsPayload}"
            }
        ]
    },
    {
        "type": "Container",
        "items":[
            {
                "type": "TextBlock",
                "text": "Settings payload",
                "$when": "${$host.isSettingsPayload}"
            }
        ]
    }
],
"actions": [
    {
        "type": "Action.Execute",
        "title": "Increment",
        "verb": "inc",
        "$when": "${!$host.isSettingsPayload}"
    },
    {
        "type": "Action.Execute",
        "title": "Update Setting",
        "verb": "setting",
        "$when": "${$host.isSettingsPayload}"
    }
],
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6"
}