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

对于自适应卡片小组件,请使用 自适应卡片 JSON 模板定义 UI 和交互,并且还可以定义单独的 JSON 数据有效负载。 本文指导你完成包含数据绑定和条件布局的计数小组件模板。 Windows小组件还可以显示 URL 中的 HTML;对于该内容格式,请参阅 Web 小组件提供程序。

计数小组件

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

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

自适应卡片设计器

自适应卡片设计器是一种联机工具,用于编辑卡片 JSON 并预览其布局和数据绑定。 打开设计器以处理模板。

Important

设计器使用自己的呈现器和主机选项。 请勿假设小组件板支持它提供的功能,或者假设它提供特定于 Windows 的 $host 值。 本演练不依赖于主机预设或主机数据编辑器。 针对每个受支持的大小和主题测试Windows小组件提供程序中的最终模板。

下图说明了卡片的布局,而不是当前设计器界面。

从空白卡开始

卡片有效负载编辑器包含卡的 JSON 定义。 将其内容替换为此空白卡:

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6",
    "body": []
}

示例数据编辑器包含可选的 JSON 数据上下文。 有关将数据绑定到模板的信息,请参阅自适应卡片模板语言。

Windows小组件主机属性

Widgets Board 在运行时提供宿主属性。 在模板表达式中引用 $host 它们,例如 ${$host.widgetSize}。 这些属性与提供程序的数据有效负载分开;在示例数据中添加一个 widgetSize 字段并不会设置 $host.widgetSize。

财产 价值 说明
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 的值可以用于适当调整小部件内容。

计数小组件对其按钮使用四个 TextBlock 元素和一个 Action.Execute 操作。

添加 TextBlock 元素

从设计器的元素面板中添加四个 TextBlock 元素,或直接将它们添加到卡片 JSON 中。 应用条件布局之前,卡片有四行文本,如下所示。

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

实现条件布局

在 Card payload 编辑器中,将 body 数组替换为以下片段:

"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 有效负载。与条件性隐藏元素不同,所有元素均可见,并超出了图片的底部边框。

当小组件板评估将 $host.widgetSize 设置为 "small" 的模板时,只有小尺寸的文本块与计数一起显示:

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

将模板与服务提供商集成后,调整 Widgets Board 中固定的小组件的大小,并检查是否显示匹配的文本块。 声明要在 小组件提供程序清单中测试的每个大小。 没有Windows主机数据的通用设计器预览无法验证这些条件。

绑定到数据上下文

该示例使用一个名为 的数据属性,在第一个 count 中由 ${count} 引用。 在运行时,提供程序会将数据有效负载发送到小组件主机。 在设计时,在 示例数据 编辑器中输入以下 JSON,并启用设计器预览以检查计数绑定。 此示例数据不提供单独的Windows主机属性。

{"count": "2"}

将 {"count": "2"} 作为示例数据时,模板扩展会将第一个 TextBlock 中的 ${count} 替换为 2。 启用预览后,请在设计器中检查此绑定。 检查小组件板中的单独 $host.widgetSize 条件,如上所述。

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

添加按钮

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

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

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

type 属性选择 Action.Execute,小组件主机会将其转发给你的提供程序的 OnActionInvoked 回调。 请改用 Action.OpenUrl 进行 URL 导航;它不调用该提供程序回调。 title 提供按钮文本,verb 是提供程序处理的应用定义操作。 如果 $host.isUserContextAuthenticated 为 false,则不提供 Action.Execute 交互;仅支持 Action.OpenUrl 。

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

完整的小组件模板

以下代码列表显示了计数小组件交互的最终模板。 其 Action.Execute 按钮需要经过身份验证的用户上下文。 在小组件板中结合提供程序对其进行验证;设计器不会运行提供程序的递增处理程序。

{
    "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"
}