使用自适应卡片设计工具创建组件模板

注释

一些信息与预发布产品相关,在商业发行之前可能发生实质性修改。 Microsoft对此处提供的信息不作任何明示或暗示的保证。

重要

本主题中所述的功能在从版本 25217 开始的 Windows 开发者通道预览版本中提供。 有关 Windows 预览版的信息,请参阅 Windows 10 Insider Preview

Windows 小组件的 UI 和交互是使用 自适应卡片实现的。 每个小组件都提供视觉模板,还可以选择使用符合自适应卡片架构的 JSON 文档定义的数据模板。 本文将带你逐步了解如何创建简单控件模板的步骤。

计数小组件

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

应用需要实现小组件提供程序来生成和更新小组件模板和/或数据,并将其传递给小组件主机。 本文 在 win32 应用中实现小组件提供程序 提供了关于如何为计数小组件实现小组件提供程序的分步指南。我们将在接下来的步骤中生成这个计数小组件。

自适应卡片设计器

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

从预设中创建一个空模板

在页面顶部的 “选择宿主应用” 下拉列表中,选择“部件板”。 这将设置自适应卡片的容器大小为小组件所支持的尺寸。 请注意,小组件支持小型、中型和大型大小。 默认模板的大小是小组件的合适大小。 如果内容溢出边框,请不要担心,因为我们将将其替换为设计在小组件内部的内容。

页面底部有三个文本编辑器。 标记为卡片负载编辑器的内容是用于定义小组件用户界面的JSON。 标有 示例数据编辑器 的编辑器包含 JSON,用于定义您的小组件的可选数据上下文。 渲染小组件时,数据上下文动态绑定到Adaptive Card。 有关自适应卡片中的数据绑定的详细信息,请参阅 自适应卡片模板语言

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

资产 价值 DESCRIPTION
host.widgetSize “小”、“中”或“大” 固定的小组件的大小。
host.hostTheme “亮”或“暗” 显示小组件板的设备当前主题。
host.isSettingsPayload 真 或 假 如果此值为 true,则用户已单击小组件上下文菜单中的“ 自定义小组件 ”按钮。 可以使用此属性值显示自定义设置 UI 元素。 这是使用 IWidgetProvider2.OnCustomizationRequested 更改小组件提供程序应用中 JSON 有效负载的替代方法。 有关详细信息,请参阅 “实现小组件自定义”。
主机.支持页眉 真 或 假 如果此值为 true,则支持标头自定义。 有关详细信息,请参阅 isHeaderSupported
host.isHeader 真 或 假 如果此值为 true,主机将请求一个专门用于渲染小组件标头的有效负载。
host.isWebSupported 真 或 假 如果此值为 false,主机当前不支持加载小组件的 Web 内容。 当发生这种情况时,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"}

请注意,预览版现在将指定的 计数 属性的值插入到第一个 文本块的文本中。

正在制作自适应卡片。第一行文本现在包含数据载荷中的值 2。

添加按钮

下一步是向小组件添加按钮。 在小组件主机中,当用户单击按钮时,主机将向小组件提供程序发出请求。 对于此示例,部件提供程序将增加计数值并返回更新后的数据包。 由于此操作需要控件提供者,因此无法在自适应卡片设计器中查看此行为,但您仍然可以使用设计器调整 UI 中按钮的布局。

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

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

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

最终的自适应卡。一个带有“Increment”文本的蓝色按钮显示在两行文字之后。

完整的小组件模板

以下代码列表显示 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.Submit",
    "title": "Increment",
    "verb": "inc",
    "$when": "${!$host.isSettingsPayload}"
    },
    {
    "type": "Action.Submit",
    "title": "Update Setting",
    "verb": "setting",
    "$when": "${$host.isSettingsPayload}"
    }
],
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6"
}