了解使用xml为列表控件绑定数据的各种不同的方法。
介绍
在web开发项目中,我们需要经常写一些代码从数据源读取动态数据到列表控件中。在经典asp时期,这是一件相对比较困难的任务。例如,我们必须查询数据库,找回 recordset 并且在手动创建html标签时还要重述 recordset 。
现在在asp.net中,你做同样的事情有了更好的办法。此外,除了用数据库作为数据源,你还可以使用各种数据源,比如xml文件。哪一个更好呢?这会在性能、适应性、可靠性、易配置性、安全等方面引起争论。在这里,我不想讨论这些。
这篇文章讨论了几种可选择的办法给列表控件绑定不同类型的数据源(主要是xml文件)。尽管我们使用listbox 作为例子,但你可以很容易地把这种技术扩展到其他从 system.web.ui.webcontrols.listcontrol 类继承而来的列表控件。它们包括 checkboxlist、 dropdownlist 和 radiobuttonlist。
硬编码列表框
作为开始,让我们回忆一下通常我们是怎样用html定义一个列表框 (listbox) 的。下面展示了一个列表框的原始代码。这是最简单的方法,且费用最少,但是缺少一些弹性来控制列表框的行为。
<select size=”1″ id=”lstpizzatopping”>
<option value=”supreme”>supreme</option>
<option value=”italianclassic”>italian classic</option>
<option value=”meatlover”>meat lover</option>
</select>
在asp.net中,你可以使用列表框得到同样的结果,但是具有更多性能来控制它的行为和属性。
<asp:listbox rows=”1″ id=”lstpizzatopping” runat=”server”>
<asp:listitem value=”supreme”>supreme</asp:listitem>
<asp:listitem value=”italianclassic”>italian classic</asp:listitem>
<asp:listitem value=”meatlover”>meat lover</asp:listitem>
</asp:listbox>
让我们在代码中使用一点手法。除了在列表框中硬编码进去一些项,你可以使用listitem 对象生成一些项添加到列表框控件中。listitem 有两个参数,项的文字以及值。如果你没指定第二个参数,那项的值将跟它的文字一样。下面的代码演示了该怎么做:
<script runat=”server”>
sub page_load(src as object, e as eventargs)
lstpizzatopping.items.add(new listitem(“supreme”, “supreme”))
lstpizzatopping.items.add(new listitem(“italian classic”, “italianclassic”))
lstpizzatopping.items.add(new listitem(“meat lover”, “meatlover”))
</script>
…
…
<asp:listbox rows=”1″ id=”lstpizzatopping” runat=”server” />
列表框绑定数据
事实上,asp.net允许你把列表框的内容跟对象绑定起来。这个对象可以是一个数组,一个集合对象,一个数据库甚至是一个xml文件。下面的例子演示了怎么把一个字符串数组绑定到列表框控件上。我们将在后面更详细地探究xml数据的绑定。
<script runat=”server”>
sub page_load(src as object, e as eventargs)
dim arrpizzatopping as string() = _
{ “supreme”, “italian classic”, “meat lover” }
lstpizzatopping.datasource = arrpizzatopping
lstpizzatopping.databind()
end sub
</script>
…
…
<asp:listbox rows=”1″ id=”lstpizzatopping” runat=”server” />
如果我们给数组添加一个新的元素会怎么样?列表框会反映出结果吗?不会的,除非你再一次使用 databind 方法。利用这种数据绑定技术,在什么时候什么地方更新列表框,你拥有完全的控制权。
让我们看看另外一个例子,在asp.net中用 arraylist 对象绑定数据。这个 arraylist 跟vb中的数组有点相似,但是它功能更强,它能支持更多复杂的数据类型。arraylist d实际上是一个集合,所以我们可以把它作为一个集合。添加一个新项,我们调用 add 方法并提供对象去 add,在这种情况下它是一个字符串。
<script runat=”server”>
sub page_load(src as object, e as eventargs)
dim arrpizzatopping as new arraylist()
arrpizzatopping.add(“supreme”)
arrpizzatopping.add(“italian classic”)
arrpizzatopping.add(“meat lover”)
lstpizzatopping.datasource = arrpizzatopping
lstpizzatopping.databind()
end sub
</script>
…
…
<asp:listbox rows=”1″ id=”lstpizzatopping” runat=”server” />
数据绑定是把脚本跟用户界面分离开来的一个例子(比如html代码)。但是像我们上面提到的数据绑定技术,我们只能绑定静态数据(这些数据应该被硬编码进我们的aspx 文件)。 如果数据是动态将会怎么样?如果我们想在其他页面重用列表框,又会怎么样?为了解决这些问题,我们需要依赖于额外的数据源。典型的,我们使用数据库把列表框中的内容存储在表中。有很多文章以及讨论了这种技术。举例来说,你可以查阅scott mitchell 关于用access数据库为列表控件绑定数据的文章。
关于数据库的讲了很多,现在我们试着使用一下另一种方法——xml文件。xml文件是一个纯文本文件,所以你可以很容易地用记事本创建和编辑它。下面的代码块是包含提供给列表框控件数据的xml文件的一个例子。它有两个部分,这由注释很清晰地标识出来。第一部分包含了关于”pizza toppings”的列表,第二部分包含了关于”pizza crust”的列表。每一部分有多个条目,在每一条目中又有 <value> 和 <desc> 两个元素。请记住,这个xml文件只是一个例子。你能定义你自己的元素和内容。好像你已经饿了,但是别抱怨我。无论如何, pizza 和编程是非常匹配的。
<?xml version=”1.0″ standalone=”yes” ?>
<lookup>
<!– start of: topping –>
<topping>
<value>supreme</value>
<desc>supreme</desc>
</topping>
<topping>
<value>italianclassic</value>
<desc>italian classic</desc>
</topping>
<topping>
<value>meatlover</value>
<desc>meat lover</desc>
</topping>
<!– end of: topping –>
<!– start of: crust –>
<crust>
<value>original</value>
<desc>original crust</desc>
</crust>
<crust>
<value>handstretched</value>
<desc>hand-stretched crust</desc>
</crust>
<crust>
<value>pan</value>
<desc>pan crust</desc>
</crust>
<!– end of: crust –>
</lookup>
现在开始变魔术了。在这个xml文件中没有什么特别的,除非你把它加载到ado.net的dataset中。ado.net 强有力地支持xml,它可以在xml文件上建立一个关系信息。举各例子,提供前面提到的那个xml文件,ado.net将自动创建一个名为lookup的dataset,它包含两张表:tooping和crust。表tooping有两列(value和desc)三行。同样的,表crust也有(value和desc)三行。ado.net是通过模式来读和构造这些表的。下面的图形象的表示了dataset 和它的 datatable。
为了把xml文家加载到dataset 中,你要使用下面的代码。第一行创建了一个新的 dataset 实例。 第二行调用了readxml 方法并把xml文件的完整路径传递过去。我们使用 server.mappath 把文件的虚拟路径转换成物理路径。
dim mydataset as dataset = new dataset
mydataset.readxml(server.mappath(“lookup.xml”))
把表绑定到列表框是简单的。我们仅仅设置一下列表框的datasource 和 datamember 属性,使其指向特定的表,然后调用databind 方法就可以了。别忘了设置 datatextfield 和 datavaluefield 属性,它们显示哪一列是作为值来使用,哪一列是作为文本来使用,因为asp.net是不能自动决定的!
<script runat=”server”>
sub page_load(src as object, e as eventargs)
…
…
lstpizzatopping.datasource = mydataset
lstpizzatopping.datamember = “topping”
lstpizzatopping.databind()
end sub
</script>
…
…
<asp:listbox rows=”1″
id=”lstpizzatopping”
datatextfield=”desc”
datavaluefield=”value”
runat=”server” />
在列表框中排序
有时候,你想要顺序的排列你的项。下面的代码演示了这种情况。第一行创建了一个表 topping的缺省视图,名为mydataview 的实例。第二行把sort 属性设置为desc asc,让desc列中的数据升序排列。下一行,我们把列表框的 datasource属性设置为 mydatview,然后调用 databind方法有效地传递列表框的内容。
dim mydataview as dataview = mydataset.tables(“topping”).defaultview
mydataview.sort = “desc asc”
lstpizzatopping.datasource = mydataview
lstpizzatopping.databind()
性能问题
因为数据绑定是一个损耗资源的过程,所以你应该只在你需要的时候绑定列表控件。你应该在列表控件的内容是动态时,或者在要故意重用列表控件时绑定数据。后者比如同样一个列表框在多个页面显示。当你需要改变这些列表框的内容时,你会节省很多时间,因为你不需要一个个去修改。如果没有一个原因适合你,为了避免不必要的开支,你可以硬编码列表控件的内容。
在列表框中排列项也是需要耗费一定的资源。如果你想要列表框在任何地方任何时间都是排列号的,考虑用排列好的顺序编写xml文件,而不是在编程时排列列表框中的项。
结论
这篇文章介绍了在web页面上处理列表控件的各种方式。它从简单易懂的硬编码技术开始,使用 array、arraylist 绑定数据,最后使用xml来绑定数据。用xml绑定数据是一种你可以考虑代替数据库的数据绑定方法。它很容易实现,而且能避免sql数据库给企业带来的高额费用。