快速入门:添加 ListView (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

大多数应用都显示数据列表(如联系人列表、库中的图像或电子邮件收件箱的内容)。这些列表可以从数据库、Web 或 JSON 数据源获取其数据。 WinJS 提供可用来显示数据的 ListView 控件。

先决条件

你应当能够创建使用 JavaScript 的基本 Windows 运行时应用,该应用使用 WinJS 控件。有关如何开始使用 WinJS 控件的说明,请参阅快速入门:添加 WinJS 控件和样式

什么是 ListView?

ListView 是一种 WinJS 控件,它以可自定义的列表或网格形式显示来自 IListDataSource 的数据。 WinJS 提供以下几种类型的 IListDataSource 对象:

还可以创建自定义数据源,以便连接到某些其他类型的数据提供程序,如 Web 服务或数据库。有关的详细说明,请参阅如何创建自定义数据源

创建 ListView

Hh465496.wedge(zh-cn,WIN.10).gif创建 ListView

  1. 将指向 WinJS 的引用添加到你的 HTML 文件(如果文件中还没有这些引用)。

    使用最新版本的 WinJS:

    1. Get WinJS 下载最新版本,并将其复制到应用或网站的目录。
    2. 将 WinJS CSS 和脚本引用添加到使用 WinJS 功能的应用或网站的每个页面。
    
    <!-- WinJS references -->
    <link href="/WinJS/css/ui-dark.css" rel="stylesheet">
    <script src="/WinJS/js/WinJS.js"></script>
    

    此示例展示了你在 Microsoft Visual Studio 中创建新的“空白应用程序”项目时生成的 default.html 文件的 HTML。

    
    <!-- default.html -->
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>ListViewExample</title>
    
        <!-- WinJS references -->
        <link href="/WinJS/css/ui-dark.css" rel="stylesheet">
        <script src="/WinJS/js/WinJS.js"></script>
    
        <!-- ListViewExample references -->
        <link href="/css/default.css" rel="stylesheet">
        <script src="/js/default.js"></script>
    </head>
    <body>
        <p>Content goes here</p>
    </body>
    </html>
    
  2. 在 HTML 文件中,创建一个 div 元素并将它的 data-win-control 属性设置为 WinJS.UI.ListView

    <div id="basicListView" 
        data-win-control="WinJS.UI.ListView">  
    </div>
    
  3. 在 HTML 文件附带的 JavaScript 代码中,当加载 HTML 时调用 WinJS.UI.processAll 函数。

    WinJS.UI.processAll();
    

    下一示例展示了当你创建新的“空白应用程序”项目时所创建的 default.html 文件附带的 default.js 文件。

    
    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll());
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        app.start();
    })();
    

    当你将 ListView 添加到起始页 (default.html) 后此示例才生效。如果将 ListView 添加到 Page 控件,则无需调用 WinJS.UI.processAll,因为该 Page 控件将为你执行调用。如果要向你自己的自定义 HTML 中添加 ListView,可以使用 DOMContentLoaded 事件来调用 WinJS.UI.processAll。有关激活控件的详细信息,请参阅快速入门:添加 WinJS 控件和样式

此代码会创建空的 ListView。如果现在运行该应用,尚且看不到任何内容。在下一部分中,为 ListView 创建一些用于显示的数据。

定义数据

使用代码在单独的 JavaScript 文件中创建数据源,这样可使数据源更易于维护。在此部分中,你可以了解如何为数据创建 JavaScript 文件,如何创建 List 以及如何使用 WinJS.Namespace.define 函数使得其余应用可以访问该数据。

  1. 使用 Visual Studio 将数据文件添加到项目中。在解决方案资源管理器中,右键单击项目的 js 文件夹,然后选择“添加”>“新建项”。****即会出现“添加新项”对话框。

  2. 选择“JavaScript 文件”****。为其命名为 "dataExample.js"。 单击“添加”以创建文件。Visual Studio 创建一个名为 dataExample.js 的空白 JavaScript 文件。

  3. 打开 dataExample.js。创建一个匿名函数并打开严格模式。

    为基本应用编写代码中所述,通过在匿名函数中包装 JavaScript 代码来封装该代码是一个好方法,并且使用严格模式同样也是一个好的编程做法。

    (function () {
        "use strict"; 
    
    
    
    
    
    })();
    
  4. 创建数据数组。以下示例将创建一个对象数组。每个对象都有三个属性:title、text 和 image。

    (function () {
        "use strict";
    
        var dataArray = [
        { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
        { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
        { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
        { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
        { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
        { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
        { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" }
        ];
    
    })();
    

    注意  如果你要按照你的代码操作,则可以将图片更改为你的本地计算机上的文件,也可以通过下载 ListView 入门示例(它与此处的示例不是同一个示例,但它们使用相同的图像)来获取图片。该示例仍将运行而不添加图像。

     

  5. 使用数组创建 List 对象。

    (function () {
        "use strict";
    
        var dataArray = [
        { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
        { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
        { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
        { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
        { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
        { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
        { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" }
        ];
    
        var dataList = new WinJS.Binding.List(dataArray); 
    
    })();
    
  6. 通过声明命名空间并添加 List 作为其公共成员来公开 List

    由于你刚编写的代码封装在一个匿名函数中,因此该代码的任何部分都不能公开访问。这就是为什么使用匿名函数的部分原因:为了使专用数据保持私有。为了使你的 ListView 能够访问 List,你必须使其可公开访问。实现此目的的一种方法就是使用 WinJS.Namespace.define 函数创建一个命名空间并添加 List 作为它的一个成员。

    WinJS.Namespace.define 函数采用两个参数:要创建的命名空间的名称和包含一个或多个属性/值对的对象。每个属性是成员的公用名称,而每个值是在私有代码中要公开的基础变量、属性或函数。

    以下示例创建一个名为 DataExample 的命名空间,该命名空间公开一个名为 itemList 且返回 List 的公共成员。

    (function () {
        "use strict";
    
        var dataArray = [
        { title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
        { title: "Banana blast", text: "Ice cream", picture: "images/60banana.png" },
        { title: "Brilliant banana", text: "Frozen custard", picture: "images/60banana.png" },
        { title: "Orange surprise", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Original orange", text: "Sherbet", picture: "images/60orange.png" },
        { title: "Vanilla", text: "Ice cream", picture: "images/60vanilla.png" },
        { title: "Very vanilla", text: "Frozen custard", picture: "images/60vanilla.png" },
        { title: "Marvelous mint", text: "Gelato", picture: "images/60mint.png" },
        { title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" }
        ];
    
        var dataList = new WinJS.Binding.List(dataArray);
    
        // Create a namespace to make the data publicly
        // accessible. 
        var publicMembers =
            {
                itemList: dataList 
            };
        WinJS.Namespace.define("DataExample", publicMembers); 
    
    })();
    

你创建了一个可以由你的 ListView 访问的数据源。 接着,需要将该数据连接到 ListView

将数据连接到 ListView

  1. ListView 所在 HTML 文件的 head 部分中,将引用添加到刚创建的数据文件 (dataExample.js) 中:

    <head>
        <!-- Other file references ... -->
    
        <!-- Your data file. -->
        <script src="/js/dataExample.js"></script>
    
    </head>
    
  2. 使用在上一部分中创建的数据设置 ListView 控件的 itemDataSource 属性。

    itemDataSource 属性接受 IListDataSource 对象。List 对象不是 IListDataSource,但该对象确实具有 dataSource 属性,该属性返回自身的 IListDataSource 版本。

    若要连接数据,请将 ListView 控件的 itemDataSource 属性设置为 DataExample.itemList.dataSource

    
    <div id="basicListView"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{ itemDataSource : DataExample.itemList.dataSource }">
    </div>  
    

运行该应用。ListView 显示数据源中的属性和值:

显示没有模板的数据源内容。

这完全不是我们想要的外观。我们只想显示标题和文本字段的值,而且希望显示实际图像(而不是指向图像的路径)。若要获取我们所需的呈现外观,需要定义 Template。下一个步骤会显示方法。

定义项模板

此时,ListView 具备所需的数据,但不了解如何显示该数据。为此,你需要一个项模板,其中包含要用来显示每个列表项的标记。项模板可以包含大多数其他控件(有关详细信息,请参阅添加交互元素部分),但不能包含 FlipView 或另一个 ListView

创建模板的方式有以下两种:可以使用标记定义 WinJS.Binding.Template,也可以创建模板化功能。此示例会创建标记模板。有关创建模板化功能的信息,请参阅 itemTemplate 属性。

WinJS.Binding.Template 可轻松创建:定义要用于显示每个列表项的标记,然后指示每个数据字段的显示位置。

  1. 在 HTML 中,创建 WinJS.Binding.Template 控件并为其分配 ID。以下示例使用 ID "mediumListIconTextTemplate"。

        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
    
        </div>
    

    注意  你必须先定义模板然后才能使用它,因此请在你的 ListView 的 HTML 之前添加我们的模板的 HTML。

     

  2. WinJS.Binding.Template 必须具有单个根元素。创建用作模板父内容的 div 元素。

        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
            <div>
    
            </div>
        </div>
    
  3. 创建 ListView 将为其包含的每个数据项生成的标记。 在上一步中创建的数据包含图像位置、标题和文本,因此,请创建以下元素:

    • 用于显示图片字段的 img 元素。
    • 用于显示标题字段的 h4 元素。
    • 用于显示文本字段的 h6 元素。
        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
            <div>
    
                <!-- Displays the "picture" field. -->
                <img src="#"  />
                <div>
    
                    <!-- Displays the "title" field. -->
                    <h4></h4>
    
                    <!-- Displays the "text" field. --> 
                    <h6></h6>
                </div>
            </div>
        </div>
    
  4. 为了避免布局问题,请始终指定模板中根元素和 img 元素的大小。

        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
            <div style="width: 150px; height: 100px;">
    
                <!-- Displays the "picture" field. -->
                <img src="#" style="width: 60px; height: 60px;" />
                <div>
    
                    <!-- Displays the "title" field. -->
                    <h4></h4>
    
                    <!-- Displays the "text" field. --> 
                    <h6></h6>
                </div>
            </div>
        </div>    
    
  5. 为显示数据的每个元素设置 data-win-bind 属性。data-win-bind 属性使用以下语法:

    data-win-bind="propertyName: dataFieldName"

     

    例如,若要将 imgsrc 属性绑定到 "picture" 字段,使用以下语法:

    <img data-win-bind="src : picture" />
    

    若要设置多个属性,可以使用分号将其分隔:

    data-win-bind="property1Name: dataField1Name; property2Name: dataField2Name"

     

    此示例将模板中的项绑定到其相应的数据字段中。

        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
            <div style="width: 150px; height: 100px;">
    
                <!-- Displays the "picture" field. -->
                <img src="#" style="width: 60px; height: 60px;" 
                     data-win-bind="alt: title; src: picture" />
                <div>
    
                    <!-- Displays the "title" field. -->
                    <h4 data-win-bind="innerText: title"></h4>
    
                    <!-- Displays the "text" field. --> 
                    <h6 data-win-bind="innerText: text"></h6>
                </div>
            </div>
        </div>    
    
  6. 若要使用项模板,请使用 select 语法将 ListViewitemTemplate 属性设置为你的项模板。

        <div id="mediumListIconTextTemplate" data-win-control="WinJS.Binding.Template">
            <div style="width: 150px; height: 100px;">
    
                <!-- Displays the "picture" field. -->
                <img src="#" style="width: 60px; height: 60px;" 
                     data-win-bind="alt: title; src: picture" />
                <div>
    
                    <!-- Displays the "title" field. -->
                    <h4 data-win-bind="innerText: title"></h4>
    
                    <!-- Displays the "text" field. --> 
                    <h6 data-win-bind="innerText: text"></h6>
                </div>
            </div>
        </div>       
    
        <div id="basicListView" data-win-control="WinJS.UI.ListView" 
            data-win-options="{itemDataSource : DataExample.itemList.dataSource, 
                itemTemplate: select('#mediumListIconTextTemplate')}">
        </div>
    

    如果立即运行应用,则绑定的数据会出现在列表中。

    用于显示图像和文本的数据绑定 ListView。

设置 ListView 的样式

ListView 不会动态调整其高度以适应你的内容。为了使 ListView 能够呈现,你必须为其指定绝对的高度值。WinJS 样式表将 ListView 控件的高度设置为 400 像素,但通过使用自己的 CSS 覆盖默认样式,可以轻松指定自己的高度。将此 CSS 添加到你的应用的 CSS 文件可以设置 ListView 的高度和宽度并为其提供边框:

Windows 的 ListView 样式

.win-listview 
{
    height: 500px; 
    width: 500px; 
    border: 2px solid gray;
}

Windows Phone 8.1 的 ListView 样式

.win-listview 
{
    height: 400px; 
    width: 300px; 
    border: 2px solid gray;
}

win-listview 是一个由 WinJS 定义的类,可用来设置 ListView 的样式。刚刚看到的示例更改每个 ListView 的高度、宽度和边框。若要仅更改一个 ListView,请将托管 div 元素的 ListView 控件的 ID 添加到选择器中:

Windows 的特定 ListView 样式

#basicListView .win-listview 
{
    height: 500px; 
    width: 500px; 
    border: 2px solid gray;
}

Windows Phone 8.1 的特定 ListView 样式

#basicListView .win-listview 
{
    height: 400px; 
    width: 300px; 
    border: 2px solid gray;
}

运行该应用。现在,ListView 足够大,可以显示所有的项。

500px 的 ListView 控件。

你可以替代 WinJS 样式表所定义的 CSS 类,从而自定义 WinJS 控件的外观。用于 ListView 的 CSS 类包括:

  • win-listview

    指定 ListView 本身的样式。

  • win-container

    指定 ListViewFlipView 项容器的样式。每一项都有其各自的容器。

  • win-progress

    指定在 ListView 加载相关项时所显示的进度控件的样式。

有关完整的列表,请参阅 ListView reference page

此示例定义的样式将在 ListView 中的每个项容器周围添加一个边距。


#basicListView .win-listview .win-container {
    margin: 10px; 
}

ListView 中带有样式的项目

下一个示例定义的样式适用于处在悬停状态的 ListView 中的列表项。

#basicListView .win-listview .win-container:hover {
    color: red;
}

注意  

ListView 支持左边距、上边距和下边距,但是你不能指定右边距。一个解决方法就是添加一个具有所需宽度的元素,并将它的 style.visibility 属性设置为“none”,然后将该元素添加到 ListView 的右侧。

 

设置项的样式

上面的几个示例使用级联样式和 WinJS 类来设置 ListView 及其各项的样式。你还可以使用 CSS 类来设置项模板的样式。下一个示例更新你在定义项模板部分中定义的模板。它将删除已定义的级联样式并添加一些 CSS 类。

    <div id="mediumListIconTextTemplate" 
         data-win-control="WinJS.Binding.Template" 
         style="display: none">
        <div class="mediumListIconTextItem">
            <img src="#" class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
            <div class="mediumListIconTextItem-Detail">
                <h4 data-win-bind="innerText: title"></h4>
                <h6 data-win-bind="innerText: text"></h6>
            </div>
        </div>
    </div>

将以下样式添加到你的应用的 CSS 中:

.mediumListIconTextItem
{
    width: 282px;
    height: 70px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .mediumListIconTextItem img.mediumListIconTextItem-Image 
    {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .mediumListIconTextItem .mediumListIconTextItem-Detail
    {
        margin: 5px;
        -ms-grid-column: 2;
    }

现在,ListView 看上去如下所示:

项已设置样式的 ListView

你不必从头创建模板样式。 有关一组常用的模板及其相应的 CSS,请参阅列表布局的项模板网格布局的项模板

在列表、网格和单元布局之间切换

ListView 元素有三个布局模式:列表、网格和单元。

  • 若要使用列表布局,请将 layout 属性设置为 WinJS.UI.ListLayout,如下所示:

        <div id="basicListView" 
            data-win-control="WinJS.UI.ListView"
            data-win-options="{ itemDataSource : DataExample.itemList.dataSource, 
                itemTemplate: select('#mediumListIconTextTemplate'), 
                layout: {type: WinJS.UI.ListLayout}}">
        </div>  
    
  • 若要使用网格布局,请将 layout 属性设置为 WinJS.UI.GridLayout,如下所示:

        <div id="basicListView" 
            data-win-control="WinJS.UI.ListView"
            data-win-options="{ itemDataSource : DataExample.itemList.dataSource, 
                itemTemplate: select('#mediumListIconTextTemplate'), 
                layout: {type: WinJS.UI.GridLayout}}">
        </div>  
    
  • (仅限 Windows)若要使用单元布局,请将布局属性设置为 WinJS.UI.CellSpanningLayout,如下所示:

        <div id="basicListView" 
            data-win-control="WinJS.UI.ListView"
            data-win-options="{ itemDataSource : DataExample.itemList.dataSource, 
                itemTemplate: select('#mediumListIconTextTemplate'), 
                layout: {type: WinJS.UI.CellSpanningLayout}}">
        </div>  
    

你可以随时更改 ListView 的布局,即使在创建它之后也可以进行更改。

对数据进行分组

可以对 ListView 中的项进行分组。下图显示按字母顺序分组的项:

带有分组项的 ListView

若要了解具体做法,请参阅如何对 ListView 中的项进行分组

向项模板中添加交互元素

注意  项模板可以包含大多数其他控件,但不能包含 FlipView 或另一个 ListView

 

选择和调用 ListView 项目

通常,当用户与某个元素交互时,ListView 会捕捉该交互并使用它来确定用户是选择或调用了某个项目还是正在项目之间平移。为了使交互元素(如控件)接收输入,必须将 win-interactive CSS 类附加到交互元素或它的某个父元素。该元素及其子元素接收交互而且不再针对 ListView 触发事件。

当你将 win-interactive 附加到项模板中的某个元素时,请确保该元素不填满整个项目,否则用户将无法选择或调用该项目。

若要向项模板添加交互元素,我们建议你使用模板函数而非 WinJS.Binding.Template。 有关模板函数的详细信息,请参阅如何创建模板函数

向 ListView 添加重新排序、拖动和放置功能(仅限 Windows)

ListView 控件也可以让用户重新排序、拖和放单个项目。例如,你可以通过将 ListViewitemsDraggable 属性设置为“真”来声明拖动功能。同样,要允许用户在 ListView 控件中重新排列项目顺序,你可以将 ListViewitemsReorderable 属性设置为“真”。

<div id="basicListView" 
        data-win-control="WinJS.UI.ListView"
        data-win-options="{ itemDataSource : DataExample.itemList.dataSource, 
            itemTemplate: select('#mediumListIconTextTemplate'), 
            itemsDraggable: true,
            itemsReorderable: true }">
</div>  

itemsDraggable 属性允许从 ListView 控件以可见方式拖动单个项目。当用户从 ListView 拖动项目时,会引发 itemdragstart 事件。(该事件在重新排序操作开始时也会被引发。)将项目放到 ListView 中时,ListView 会引发 itemdragdrop 事件。

有关添加重新排序、拖或放功能到 ListView 控件的详细信息,请参阅如何在 ListView 中启用重新排序和拖放或下载 HTML ListView 拖放和重新排序示例

ListView 示例

有关几乎每一个 WinJS 控件的实时代码示例和联机编辑器,请参阅 try.buildwinjs.com

这些其他示例可帮助你了解有关 ListView 控件的详细信息。

摘要和后续步骤

你学习了如何创建 ListView 以及如何将它与数据绑定。你还学习了如何创建项模板并设置它们的样式。

有关可以用在应用中的预定义项模板的列表,请参阅列表布局的项模板网格布局的项模板。若要了解如何对项进行分组,请参阅如何对 ListView 中的项进行分组