数据绑定和使用 ObjectList 控件查看数据

更新:2007 年 11 月

您可以使用 ObjectList ASP.NET 移动控件提供全面的数据视图。此控件显示数据源的两个视图:一个显示各项摘要的列表视图和一个显示项详细信息的视图。您可以显式定义要为每个项显示的列表字段,或者可以从数据源中自动生成这些列表字段。默认情况下,此控件为数据源中的每个字段生成一个字段,其顺序为字段在数据源中出现的顺序。每个自动生成的字段的名称将用作字段标题。

您可以将 ObjectList 控件中的数据绑定到 DataViewDataSet 对象。若要将 ObjectList 移动控件中的数据绑定到 DataView 对象,请设置 DataSource 属性,然后调用 DataBind 方法来执行数据绑定。例如,如果有一个 DataSet 对象包含一个名为 Titles 的表,则可以使用以下语句执行数据绑定:

myObjectList.DataSource = ds.Tables["Titles"].DefaultView;
myObjectList.DataBind();

或者,若要将数据直接绑定到 DataSet 对象,还必须将 DataMember 属性设置为该表的名称。下面的示例与前一个示例是等同的:

myObjectList.DataSource = ds;
myObjectList.DataMember = "Titles";
myObjectList.DataBind();

您也可以将项字段设置为由数据项的几个属性组成的值。为此,您可以重写 ObjectList 控件的 ItemDataBind 事件,并以编程方式设置该字段。下面的示例将 Summary 字段设置为书名和价格的组合:

private void ObjectList_OnItemDataBind(Object sender, 
    ObjectListDataBindEventArgs e)
{
    e.ListItem["Summary"] = String.Format( String.Format ("{0} – {1}", 
        DataBinder.Eval(e.DataItem, "title"),
        DataBinder.Eval (e.DataItem, "price")));
}

此外,您还可以控制如何在列表视图中呈现每个项。默认情况下,列表视图使用第一个字段来表示每个项。但是,您可以将 LabelField 属性设置为任何定义的或自动生成的字段(包括在详细信息视图中不可见的字段)。采用上面的示例,您可以使用 Summary 字段作为项的标签,而在详细信息视图中隐藏该字段。

在 ObjectList 中执行数据绑定

只有当 ObjectList 控件绑定到数据源时,它才会显示内容。数据源可以是实现 IEnumerable 接口或 IListSource 接口的任何对象。但是,数据源中的每个对象必须属于同一个类,或者必须从同一个公共类继承。当 AutoGenerateFields 设置为 true 时,数据源中的对象必须为同一类。

对于数据源中的每个对象,ObjectList 控件将构造一个 ObjectListItem 实例,并将其存储在它的 Items 集合中。您的代码可以检查但不能修改该集合。

对象列表引用的所有属性都必须是数据源中的所有对象共有的类的公共属性。字段引用的所有属性也必须属于可绑定的类型。有效的可绑定类型包括 StringDateTimeDecimal 以及基元类型集。

对于数据源中的每个对象,此控件执行以下数据绑定步骤:

  1. 对于每个字段,ObjectList 控件使用该字段的 DataField 属性确定要查找数据对象的哪项属性。每个值作为索引字段值保存在 ObjectListItem 实例中。

  2. 以这种方式绑定所有字段后,此控件将调用为 ObjectList 控件定义的任何 ItemDataBind 事件处理程序。您可以使用该处理程序执行更为复杂的数据绑定并设置 ObjectListItem 实例中的值。

    说明:

    ObjectList 控件的某些更改将要求您重新绑定该控件上的数据。这些更改包括添加或移除字段、更改字段的 DataField 属性以及更改字段的 DataFormatString 属性。

在数据绑定过程中启动自动字段生成

在数据绑定过程中,如果 AutoGenerateFields 属性设置为 true,ObjectList 控件将检查数据源,然后自动生成字段。如果数据源是类型为 ITypedList 的列表,ObjectList 控件将检查该类型的信息。否则,ObjectList 控件将检查列表中第一个对象的类型信息。

对于已检查的类型的每个可绑定的公共属性,ObjectList 控件将生成绑定到该属性的字段。这在数据绑定时发生;如果您更改字段或者添加或移除字段,则必须再次绑定属性。

默认情况下,自动生成的字段是可见的,它们使用默认格式设置,并且具有与属性名称相同的标题。所有这些值都可以通过编程方式进行更改。另外,您还可以通过在属性 (Property) 中添加 ObjectListTitleAttribute 属性 (Attribute) 来指定字段的标题。例如,如果对象有声明为 [ObjectListTitle("Address")]myAddress 的属性,所生成的字段将具有标题“Address”。

如果 ObjectList 控件具有显式定义的字段,自动生成的字段将添加在这些字段的后面。

下面的示例演示如何在 ObjectList 控件中显示自定义对象的列表。

<%@ Page Language="VB" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>

<script runat="server">
    Private customers(3) As Person

    Private Class Person
        Private _Name, _Nickname, _Initials As String

        Public Sub New(ByVal name As String, _
            ByVal nickname As String, _
            ByVal initials As String)

            Me._Name = name
            Me._Nickname = nickname
            Me._Initials = initials
        End Sub

        Public ReadOnly Property Name() As String
            Get
                Return _Name
            End Get
        End Property
        Public ReadOnly Property Nickname() As String
            Get
                Return _Nickname
            End Get
        End Property
        Public ReadOnly Property Initials() As String
            Get
                Return _Initials
            End Get
        End Property
    End Class

    Private Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs)

        ReDim customers(2)
        customers(0) = _
            New Person("George Washington", "George", "GW")
        customers(1) = _
            New Person("Abraham Lincoln", "Abe", "AL")
        customers(2) = _
            New Person("Theodore Roosevelt", "Teddy", "TR")

        If (Not IsPostBack) Then
            ' Bind the array to the list.
            List1.DataSource = customers
            List1.DataTextField = "Name"
            List1.DataBind()
        End If
    End Sub

    Protected Sub List1_ItemCommand( _
        ByVal sender As Object, _
        ByVal e As ListCommandEventArgs)

        ' Show the Summary text
        Dim selectedPerson As Person = _
            customers(e.ListItem.Index)
        Label1.Text = _
            String.Format("{0} (AKA {1}), initials {2}", _
            selectedPerson.Name, _
            selectedPerson.Nickname, _
            selectedPerson.Initials)

        ActiveForm = Form2
    End Sub

    Protected Sub Command1_Click(ByVal sender As Object, _
        ByVal e As EventArgs)

        Me.ActiveForm = Me.Form1
    End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="Form1" runat="server">
        <mobile:List ID="List1" Runat="server" 
            OnItemCommand="List1_ItemCommand" />
    </mobile:form>

    <mobile:Form ID="Form2" Runat="server">
        <mobile:Label ID="Label1" runat="server" />
        <mobile:Command ID="Command1" Runat="server" 
            StyleReference="subcommand" 
            OnClick="Command1_Click">
            Return</mobile:Command>
    </mobile:Form>
</body>
</html>
<%@ Page Language="C#" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>

<script runat="server">
    private ArrayList customers = new ArrayList();

    private class Person
    {
        private String _Name, _Nickname, _Initials;

        public Person(String name, String nickname, String initials)
        {
            this._Name     = name;
            this._Nickname = nickname;
            this._Initials = initials;
        }

        public String Name     { get { return _Name;     } }
        public String Nickname { get { return _Nickname; } }
        public String Initials { get { return _Initials; } }
    }

    private void Page_Load(object sender, System.EventArgs e)
    {
        customers.Add(
            new Person("George Washington", "George", "GW"));
        customers.Add(
            new Person("Abraham Lincoln", "Abe", "AL"));
        customers.Add(
            new Person("Theodore Roosevelt", "Teddy", "TR"));

        if(!IsPostBack)
        {
            // Bind the array to the list.
            List1.DataSource    = customers;
            List1.DataTextField = "Name";
            List1.DataBind();
        }
    }

    private void List1_ItemCommand(object sender, 
        ListCommandEventArgs e)
    {
        Person selectedPerson = (Person)customers[e.ListItem.Index];
        Label1.Text = String.Format("{0} (AKA {1}), initials {2}", 
            selectedPerson.Name, selectedPerson.Nickname,
            selectedPerson.Initials);

        ActiveForm = Form2;
    }

    protected void Command1_Click(object sender, EventArgs e)
    {
        this.ActiveForm = this.Form1;
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="Form1" runat="server">
        <mobile:List ID="List1" Runat="server" 
            OnItemCommand="List1_ItemCommand">
        </mobile:List>
    </mobile:form>
    <mobile:Form ID="Form2" Runat="server">
        <mobile:Label ID="Label1" runat="server" />
        <mobile:Command ID="Command1" Runat="server" 
            OnClick="Command1_Click">Return</mobile:Command>
    </mobile:Form>
</body>
</html>

关联对象列表中的命令

ObjectList 控件允许将一组命令与一个项相关联。每个命令都有一个用于唯一地标识该命令的 Name 属性以及用于呈现该命令的 Text 属性。

此控件提供两种定义命令的方法:

默认情况下,列表中的所有项都共享同一组命令。但是,在为给定项呈现该组命令之前,此控件将引发 ShowItemCommands 事件。事件处理程序可以使用此方法为该项修改该组可视命令。

当用户选择一个命令时,将引发 ItemCommand 事件,并提供有关选定项的信息和选定命令的名称。

即使您为某个项定义了默认的命令,仍必须将命令按相同的名称包含在 Commands 集合中。如果此控件无法呈现包括默认命令快捷方式的 UI,它必须将默认命令显示为该组命令的一部分。

访问列表项的字段值

当您将事件处理程序与 ObjectList 控件相关联时,它会将列表项呈现为交互式元素。当单击一个列表项时,将生成一个检索该项的相应操作的事件。在数据绑定过程中,每个字段都将绑定到它的相应属性。

若要从 ObjectListItem 对象中检索字段值,请使用以下语法,其中 lstItem 为 ObjectListItem 实例:

lstItem[fieldName]

下面的示例类似于前一个示例,但它为每个记录使用了两个 Command 控件,并使用了字段语法来检索字段值:

<%@ Page Language="VB" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>

<script runat="server">
    Public Class Person
        ' Private Fields
        Private _Name, _Nickname, _Initials, _Wife As String

        ' Constructor
        Public Sub New(ByVal name As String, _
            ByVal nickname As String, ByVal initials As String, _
            ByVal wife As String)

            Me._Name = name
            Me._Nickname = nickname
            Me._Initials = initials
            Me._Wife = wife
        End Sub

        ' Public Properties
        Public ReadOnly Property Name()
            Get
                Return _Name
            End Get
        End Property
        Public ReadOnly Property Nickname()
            Get
                Return _Nickname
            End Get
        End Property
        Public ReadOnly Property Initials()
            Get
                Return _Initials
            End Get
        End Property
        Public ReadOnly Property Wife()
            Get
                Return _Wife
            End Get
        End Property
    End Class

    Private Sub Page_Load(ByVal sender As Object, _
        ByVal e As EventArgs)

        If Not IsPostBack Then
            ' An ArrayList for the Person objects
            Dim customers As New ArrayList()

            customers.Add( _
                New Person("George Washington", "George", _
                    "GW", "Martha"))
            customers.Add( _
                New Person("Abraham Lincoln", "Abe", _
                    "AL", "Mary"))
            customers.Add( _
                New Person("Theodore Roosevelt", "Teddy", _
                    "TR", "Alice Lee"))

            ' Bind the array to the list.
            ObjectList1.DataSource = customers
            ObjectList1.LabelField = "Name"
            ObjectList1.DataBind()
        End If
    End Sub

    Protected Sub ObjectList1_ItemCommand( _
        ByVal sender As Object, _
        ByVal e As ObjectListCommandEventArgs)

        If e.CommandName = "ShowSummary" Then
            ' Show the Summary text
            Label1.Text = _
            String.Format("{0}, AKA: '{1}', initials: '{2}'", _
                e.ListItem("Name"), e.ListItem("Nickname"), _
                e.ListItem("Initials"))
        ElseIf e.CommandName = "MoreInfo" Then
            ' Show the More Info text
            Label1.Text = String.Format("{0}'s wife was {1}", _
                e.ListItem("Nickname"), e.ListItem("Wife"))
        End If
        Me.ActiveForm = Form2
    End Sub
    Protected Sub Command1_Click(ByVal sender As Object, _
        ByVal e As EventArgs)

        ' Show the first form
        Me.ActiveForm = Form1
    End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="Form1" runat="server">
        <mobile:ObjectList ID="ObjectList1" Runat="server" 
            CommandStyle-StyleReference="subcommand"
            LabelStyle-StyleReference="title" 
            OnItemCommand="ObjectList1_ItemCommand">
            <Command Name="ShowSummary" Text="Summary" />
            <Command Name="MoreInfo" Text="More Info" />
        </mobile:ObjectList>
    </mobile:form>
    <mobile:Form ID="Form2" Runat="server">
        <mobile:Label ID="Label1" runat="server" />
        <mobile:Command ID="Command1" Runat="server" 
            OnClick="Command1_Click">Return
        </mobile:Command>
    </mobile:Form>
</body>
</html>
<%@ Page Language="C#" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>
<%@ Import Namespace="System.Collections" %>

<script runat="server">
    private class Person
    {
        // Private Fields
        private String _Name, _Nickname, _Initials, _Wife;

        // Constructor
        public Person(string name, string nickname, 
            string initials, string wife)
        {
            this._Name     = name;
            this._Nickname = nickname;
            this._Initials = initials;
            this._Wife     = wife;
        }
        // Public Properties
        public String Name     { get { return _Name;     } }
        public String Nickname { get { return _Nickname; } }
        public String Initials { get { return _Initials; } }
        public String Wife     { get { return _Wife; } }
    }

    private void Page_Load(object sender, System.EventArgs e)
    {
        if(!IsPostBack)
        {
            // An ArrayList for the Person objects
            ArrayList customers = new ArrayList();

            // Fill the Person object
            customers.Add( 
                new Person("George Washington", "George", 
                    "GW", "Martha"));
            customers.Add( 
                new Person("Abraham Lincoln", "Abe", 
                    "AL", "Mary"));
            customers.Add(
                new Person("Theodore Roosevelt", "Teddy", 
                    "TR", "Alice Lee"));

            // Bind the array to the list.
            ObjectList1.DataSource    = customers;
            ObjectList1.LabelField = "Name";
            ObjectList1.DataBind();
        }
    }

    protected void ObjectList1_ItemCommand
        (object sender, ObjectListCommandEventArgs e)
    {
        if (e.CommandName == "ShowSummary")
        {
            // Show the Summary text
            Label1.Text = 
                String.Format("{0}, AKA: '{1}', initials: '{2}'",
                    e.ListItem["Name"], e.ListItem["Nickname"], 
                    e.ListItem["Initials"]);
        }
        else if (e.CommandName == "MoreInfo")
        {
            // Show the More Info text
            Label1.Text = String.Format("{0}'s wife was {1}",
                e.ListItem["Nickname"], e.ListItem["Wife"]);
        }
        this.ActiveForm = Form2;
    }
    protected void Command1_Click(object sender, EventArgs e)
    {
        // Show the first form
        this.ActiveForm = Form1;
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="Form1" runat="server">
        <mobile:ObjectList ID="ObjectList1" Runat="server" 
            CommandStyle-StyleReference="subcommand"
            LabelStyle-StyleReference="title" 
            OnItemCommand="ObjectList1_ItemCommand">
            <Command Name="ShowSummary" Text="Summary" />
            <Command Name="MoreInfo" Text="More Info" />
        </mobile:ObjectList>
    </mobile:form>
    <mobile:Form ID="Form2" Runat="server">
        <mobile:Label ID="Label1" runat="server" />
        <mobile:Command ID="Command1" Runat="server" 
            OnClick="Command1_Click">Return
        </mobile:Command>
    </mobile:Form>

</body>
</html>

ObjectList 模板中的数据绑定

ObjectList 控件中,您可以定义模板来自定义用户的体验。如果您是在模板中执行内联数据绑定,请使用如下所示的语法:

<%#((ObjectListItem)Container)["BookName"]%> 

在所有的模板中,您还可以使用 DataBinder.Eval 方法来绑定数据,如下面的示例所示:

<%#DataBinder.Eval(((ObjectListItem)Container).DataItem,"fieldname")%>

请参见

概念

使用列表控件访问数据