实际上,DataGrid组件是属于列表组件的,之所以单独拿出来讲解,主要是因为 DataGrid组件有着很强大的功能,也有很多扩展的应用是在开发中经常用到的。DataGrid组件是按照行和列的形式显示数据的。有几个类是只有 DataGrid组件才能使用的,包括DataGridCellEditor类、DataGridColumn类和HeaderRenderer类。这三 个类会在使用的时候逐个讲解。
15.1 数据网格(DataGrid)组件简介
DataGrid组件适合显示包含多个属性的对象。可以通过内部或者外部的数据源把数 据绑定到DataGrid组件中。DataGrid组件有很多强大的功能,使我们在开发中很容易地实现某些代码,比如,按照特定的规则排序,在单元格中嵌 入其他组件等。DataGrid组件有很多属性、方法和事件。常用的属性如表15.1所示,常用的方法如表15.2所示。
表15.1 DataGrid组件常用的属性
表15.2 DataGrid组件常用的方法
可以利用这些属性、方法和事件创建强大的DataGrid组件应用程序。在接下来的几节,会逐一介绍他们的使用方法。
15.2 使用DataGrid组件显示数据列表
显示数据列表是DataGrid组件最基本的应用,只有把数据显示出来,才可以实现其 他的功能。数据的来源大概有两种,一种是内部数据,即在程序内部自定义数据,然后绑定到DataGrid组件中;另一种是外部数据,通过读取外部文件或者 是数据库,绑定到DataGrid组件中。接下来,就这两种情况分别做介绍。
15.2.1 将内部数据绑定到DataGrid组件中
要在DataGrid组件中显示数据,首先就要建立数据源,建立数据源通常是通过DataProvider API类来实现。下面的示例说明如何在DataGrid组件中显示数据,示例的步骤如下所示。
创建一个ActionScript 3.0文件,命名为DataGrid_ShowData_Example.as,类名为DataGrid_ShowData_Example,导入将用到的类库,代码如下所示:
package
{
import fl.controls.DataGrid;
import fl.controls.ScrollPolicy;
import fl.data.DataProvider;
import flash.display.Sprite;
public class DataGrid_ShowData_Example extends Sprite
{
/*****************************************
* 构造函数
* */
public function DataGrid_ShowData_Example()
{
}
}
}
创建一个函数GetData1,在内部实现具体的功能。代码如下所示:
/*********************************
* 加载内部数据,绑定DataGrid组件
* */
private function GetData1():void
{
}
在函数的内部,利用DataProvider类创建一个数据模型,这个数据模型有4列及10行数据,代码如下所示:
// 数据模型
var dp1:DataProvider = new DataProvider();
dp1.addItem({Name:"Tom", Phone:23579086, QQ:77788899, Software:"Flash"});
dp1.addItem({Name:"Kelly", Phone:33579080, QQ:56788823, Software:"Flex"});
dp1.addItem({Name:"Jim", Phone:83579085, QQ:56788882, Software:"Java"});
dp1.addItem({Name:"Sam",Phone:73579084,QQ:78988811,Software:"Dreamweaver"});
dp1.addItem({Name:"Kaiven",Phone:33576681,QQ:32188897,Software:"Photoshop"});
dp1.addItem({Name:"Gray", Phone:23229086, QQ:12388900, Software:"Fireworks"});
dp1.addItem({Name:"Luar", Phone:23579087, QQ:24681899, Software:"DAEMON Tools"});
dp1.addItem({Name:"Kite", Phone:85579082, QQ:68080894, Software:"FlashDevelop"});
dp1.addItem({Name:"Polar", Phone:32579086, QQ:21586899, Software:"Beyond Compare"});
初始化DataGrid组件,并实例化,然后设置属性,包括位置、宽度、高度、滚动条的样式等。代码如下所示:
// 初始化DataGrid组件,并实例化
var dg1:DataGrid = new DataGrid();
// 设置位置
dg1.move(20,20);
// 设置宽和高
dg1.setSize(350, 150);
dg1.verticalScrollPolicy = ScrollPolicy.AUTO;
定义列的标题,然后把数据模型和DataGrid组件绑定在一起,放到舞台上,代码如下所示:
// 定义列的标题
dg1.columns = ["Name", "Phone", "QQ", "Software"];
// 绑定数据源
dg1.dataProvider = dp1;
addChild(dg1);
编译代码并运行,效果如图15.1所示
图15.1 读取内部数据,在DataGrid中显示
15.2.2 将外部数据绑定到DataGrid组件中
外部数据通常指的是数据库、文本本件和XML文件。在实际开发中,与数据层传入数据大多是通过XML格式传输的。所以,下面就创建一个读取外部XML文件的数据,然后在DataGrid组件中显示的例子。步骤如下。
创建一个XML文件,命名为DataGrid_Data.xml,内容结构如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node label="Flash">
<Name>Flash</Name>
<Company>Adobe</Company>
<Version>9.0</Version>
</node>
<node label="Java">
<Name>Java</Name>
<Company>Sun</Company>
<Version>6.0</Version>
</node>
<node label=".Net">
<Name>.Net</Name>
<Company>Microsoft</Company>
<Version>2.0</Version>
</node>
<node label="Flex">
<Name>Flex</Name>
<Company>Adobe</Company>
<Version>2.0</Version>
</node>
<node label="OICQ">
<Name>OICQ</Name>
<Company>腾讯</Company>
<Version>2007</Version>
</node>
</root>
继续使用15.2.1节的文件,在DataGrid_ShowData_Example.as文件中,创建一个名为GetData2的函数,在函数中读取刚才创建的XML文件,代码如下所示:
/*********************************
* 加载外部XML数据
* */
private function GetData2():void
{
// 加载外部XML文件
data_xml = new XML();
myXMLURL = new URLRequest("DataGrid_Data.xml");
myLoader = new URLLoader(myXMLURL);
}
在类的外部,引入刚才使用的命名空间,包括URLRequest和URLLoader,代码如下:
import flash.net.URLRequest;
import flash.net.URLLoader;
创建上面的全局变量,data_xml、myXMLURL和myLoader。代码如下所示:
private var data_xml:XML;
private var myXMLURL:URLRequest;
private var myLoader:URLLoader;
创建XML对象的加载文件事件,并且在GetData2函数中添加侦听事件的语句,添加的侦听语句代码如下:
myLoader.addEventListener("complete", xmlLoaded);
XML对象的加载文件事件函数代码如下:
/*********************************
* 绑定DataGrid组件
* */
function xmlLoaded(event:Event):void
{
data_xml = XML(myLoader.data);
//trace(data_xml.elements("node").toXMLString());
}
在侦听事件函数中,把从外部读取的数据文件绑定到DataGrid组件中,代码如下:
// DataProvider
var dp:DataProvider = new DataProvider(data_xml);
// 初始化DataGrid组件,并实例化
var dg2:DataGrid = new DataGrid();
// 设置宽和高
dg2.setSize(200, 300);
// 定义列的标题
dg2.columns = ["Name", "Company", "Version"];
// 绑定数据源
dg2.dataProvider = dp;
addChild(dg2);
最后,在构造函数中,调用GetData2函数,代码如下:
/*****************************************
* 构造函数
* */
public function DataGrid_ShowData_Example()
{
GetData2();
}
编译代码并运行,效果如图15.2所示。
图15.2 读取外部数据绑定DataGrid组件
15.3 定义DataGrid组件样式外观
在实际程序开发中,有时候需要对DataGrid组件可视化的外观进行修改,以满足功能需要。例如,修改数据显示格式、修改DataGrid的样式和外观、自定义单元格等。
15.3.1 修改数据显示格式
当DataGrid组件显示出数据后,有些数据格式可能不是我们所需要的。这个时候,就要修改数据格式,把数据修改成有意义的,可以使读者更容易读懂的格式。比如货币格式前面要加美元符号或者人民币符号,有时候从数据库中读出的是0或1的布尔值,再比如电话号码等。
下面就以15.2.1节的实例为例,把Phone列修改成前面有区号的电话号码,步骤如下。
修改GetData1函数,在绑定数据源的语句之后,增加格式化语句,增加的代码如下所示:
// 格式化数据
dg1.getColumnAt(1).labelFunction = phoneFormatter;
phoneFormatter是格式化数据的函数,把电话号码前面加上区号“0755”,代码如下所示:
/*********************************
* 格式化电话号码
* */
private function phoneFormatter(item:Object):String
{
return "0755-" + item.Phone;
}
再次编译代码并运行,效果如图15.3所示。
图15.3 格式化电话号码
15.3.2 自定义DataGrid组件的标题
在显示完DataGrid组件的数据之后,有时候列的标题是数据库中已经定义好的列名 称,对于用户来说,不容易读懂,需要重新定义,那就需要自定义DataGrid组件的标题了。自定义标题要用到的类是 HeaderRenderer,HeaderRenderer类在类dataGridClasses中。下面就利用HeaderRenderer类来实现 自定义标题的功能。
还是以15.2.1节的实例为基础,加一些代码。在GetData1函数中加入如下代码:
// 自定义标题
var dgc0:DataGridColumn = dg1.getColumnAt(0);
dgc0.headerText = "姓名";
var dgc1:DataGridColumn = dg1.getColumnAt(1);
dgc1.headerText = "电话";
var dgc3:DataGridColumn = dg1.getColumnAt(3);
dgc3.headerText = "软件名称";
代码的作用是把第一行的标题改成“姓名”,第二行的标题改为“电话”,第三行的标题改为“软件名称”。再次编译运行,最终效果如图15.4所示。
图15.4 自定义DataGrid组件标题
15.4 DataGrid组件的分页与排序
当DataGrid组件中的数据显示很多行的时候,使用者需要不停地下拉滚动条。这对 于用户的体验极为不便,分页显示数据的方式就可以很好地解决这个问题。在应用软件开发中,分页也是常用的操作。排序的作用是为了用户可以更好地按照自己的 方式排列数据,更加方便地阅读数据信息。
15.4.1 DataGrid组件的分页
在很多语言中,分页技术都是很常见的。每种技术都有自己的优势和特点,但是基本思路都 差不多。基本思路是,把全部数据一次性读到一个数据集中,然后,再与DataGrid组件关联,分页的读取显示。另外一种思路是,先从数据库中读取一页的 数据,在DataGrid组件中显示出来,然后再读取,再显示。
下面,用第一种思路设计一个分页的程序,数据集采用数组的形式,利用数组的slice()方法,读取一部分数据,然后分页显示。步骤如下。
创建一个ActionScript 3.0文件,命名为DataGridPageExample,类名为DataGridPage- Example,继承自Sprite类,导入用到的类库。代码如下:
package
{
import fl.controls.Button;
import fl.controls.DataGrid;
import fl.controls.ScrollPolicy;
import fl.data.DataProvider;
import flash.display.Sprite;
import flash.events.MouseEvent;
public class DataGridPageExample extends Sprite
{
}
}
创建构造函数。代码如下所示:
/************************
* 构造函数
* **********************/
public function DataGridPageExample()
{
CreateDataModel();
CreateDataGrid();
CreatePageButton();
}
创建数据模型。实际开发中,是从外部数据库或者文件读取数据的,这里只是模拟数据源,便于讲解。在这里,插入了9条数据,然后传递到数组中,代码如下所示:
private var dp:DataProvider;
private var array:Array;
/************************
* 创建数据模型
* **********************/
private function CreateDataModel():void
{
// 数据模型
dp = new DataProvider();
// 插入9条数据
dp.addItem({Name:"Tom", Phone:23579086, QQ:77788899, Software:"Flash"});
dp.addItem({Name:"Kelly", Phone:33579080, QQ:56788823, Software:"Flex"});
dp.addItem({Name:"Jim", Phone:83579085, QQ:56788882, Software:"Java"});
dp.addItem({Name:"Sam", Phone:73579084, QQ:78988811, Software:"Dreamweaver"});
dp.addItem({Name:"Kaiven", Phone:33576681, QQ:32188897, Software:"Photoshop"});
dp.addItem({Name:"Gray", Phone:23229086, QQ:12388900, Software:"Fireworks"});
dp.addItem({Name:"Luar",Phone:23579087,QQ:24681899, Software:"DAEMON Tools"});
dp.addItem({Name:"Kite", Phone:85579082, QQ:68080894, Software:"FlashDevelop"});
dp.addItem({Name:"Polar",Phone:32579086,QQ:21586899,Software:"BeyondCompare"});
array = dp.toArray();
}
创建DataGrid组件,封装在函数CreateDataGrid中,代码如下所示:
private var dg:DataGrid;
// 数据副本
private var array_page:Array;
/************************
* 创建DataGrid组件
* **********************/
private function CreateDataGrid():void
{
// 初始化DataGrid组件,并实例化
dg = new DataGrid();
// 设置位置
dg.move(20,20);
// 设置宽和高
dg.setSize(350, 125);
dg.verticalScrollPolicy = ScrollPolicy.AUTO;
// 定义列的标题
dg.columns = ["Name", "Phone", "QQ", "Software"];
// 初始化数据
array_page = array.slice(0, 5);
// 绑定DataGrid组件
BingDataGrid(array_page);
addChild(dg);
}
绑定数据源,先是移除DataGrid组件中的所有数据,然后遍历参数数组中的数据,增加到DataGrid组件中。最后封装在函数BingDataGrid中,便于分页时重复调用。代码如下所示:
/************************
* 绑定数据源
* **********************/
private function BingDataGrid(array:Array):void
{
// 绑定数据源
dg.removeAll();
var i:uint = 0;
for(i=0; i<array.length; i++)
{
dg.addItem(array[i]);
}
}
创建“上一页”和”下一页“按钮,封装在函数CreatePageButton中,代码如下:
/************************
* 创建“上一页”和”下一页“按钮
* **********************/
private function CreatePageButton():void
{
var btnPre:Button = new Button();
var btnNext:Button = new Button();
btnPre.move(30, 170);
btnNext.move(240, 170);
btnPre.label = "上一页";
btnNext.label = "下一页";
btnPre.addEventListener(MouseEvent.CLICK, btnPreClick);
btnNext.addEventListener(MouseEvent.CLICK, btnNextClick);
addChild(btnPre);
addChild(btnNext);
}
创建“上一页”按钮的单击事件的函数,读取前5条数据,命名为btnPreClick,代码如下:
/************************
* “上一页”按钮的单击事件
* **********************/
public function btnPreClick(e:MouseEvent)
{
array_page = array.slice(0, 5);
BingDataGrid(array_page);
}
创建“下一页”按钮的单击事件的函数,读取后面的4条数据,命名为btnNextClick,代码如下:
/************************
* “下一页”按钮的单击事件
* **********************/
public function btnNextClick(e:MouseEvent)
{
array_page = array.slice(5, 10);
BingDataGrid(array_page);
}
把三个创建组件的函数增加到构造函数中,代码如下所示:
/************************
* 构造函数
* **********************/
public function DataGridPageExample()
{
CreateDataModel();
CreateDataGrid();
CreatePageButton();
}
最后编译运行,效果如图15.5所示。
图15.5 DataGrid组件分页
15.2 自定义DataGrid组件的单元格
DataGrid组件显示完数据之后,有些数据是需要用户自己定义或者修改的。这个时候就需要把需要用户修改的单元格变成可编辑的,以便于用户自己编辑。
15.5.1 编辑DataGrid组件的单元格
本节主要介绍如何定义一个单元格的编辑状态,下面的例子跟15.2.1节的例子差不多,但不同的是,应用了DataGridColumn类定义每个列的基本属性,然后再添加到DataGrid组件中。具体步骤如下。
创建一个ActionScript 3.0文件,命名为DataGridCellEditorExample,类名为DataGridCellEditorExample,继承自Sprite类,并导入用到的类库。代码如下所示:
package
{
import fl.controls.DataGrid;
import fl.controls.dataGridClasses.DataGridCellEditor;
import fl.controls.TextInput;
import fl.data.DataProvider;
import flash.display.Sprite;
import flash.text.TextFormat;
import fl.controls.dataGridClasses.DataGridColumn;
import fl.controls.ComboBox;
public class DataGridCellEditorExample extends Sprite
{
}
}
创建构造函数。代码如下所示:
/************************
* 构造函数
* **********************/
public function DataGridCellEditorExample()
{
}
创建DataGrid组件,封装在函数CreateDataGrid中。首先在函数中创建数据模型,代码如下所示:
/************************
* 创建DataGrid组件
* **********************/
private function CreateDataGrid():void
{
dg = new DataGrid();
// 设置大小
dg.setSize(350,300);
// 设置单元格的编辑状态
dg.editable = true;
// 创建数据模型
var dp:DataProvider = new DataProvider();
dp.addItem({Name:"Tom",Sex:"male",Phone:23579086,QQ:77788899,Software:"Flash"});
dp.addItem({Name:"Kelly",Sex:"female",Phone:33579080,QQ:56788823,Software:"Flex"});
dp.addItem({Name:"Jim",Sex:"male",Phone:83579085,QQ:56788882,Software:"Java"});
dp.addItem({Name:"Sam",Sex:"male",Phone:73579084,QQ:78988811,Software:"Dreamweaver"});
dp.addItem({Name:"Kaiven",Sex:"male",Phone:33576681,QQ:32188897,Software:"Photoshop"});
dp.addItem({Name:"Gray",Sex:"male",Phone:23229086,QQ:12388900,Software:"Fireworks"});
dp.addItem({Name:"Luar",Sex:"male",Phone:23579087,QQ:24681899,Software:"DAEMON Tools"});
dp.addItem({Name:"Kite",Sex:"female",Phone:85579082,QQ:68080894,Software:"FlashDevelop"});
dp.addItem({Name:"Polar",Sex:"male",Phone:32579086,QQ:21586899,Software:"Beyond Compare"});
在函数中,定义每个列,将性别和电话列的单元格设置成可编辑状态,添加的代码如下所示:
// 增加列,定义每个列的属性
var cellEditor:DataGridCellEditor = GetCustomEditor();
var sexcellEditor:DataGridCellEditor = GetCustomEditor_List();
// 增加定义“名字”列
var dgc_name:DataGridColumn = new DataGridColumn();
dgc_name.editable = false;
dgc_name.dataField = "Name";
//dgc_name.itemEditor = CellEditor;
dgc_name.sortable = true;
dg.addColumn(dgc_name);
// 增加定义“性别”列
var dgc_sex:DataGridColumn = new DataGridColumn();
dgc_sex.editable = true;
/dgc_sex.itemEditor = sexcellEditor;
dgc_sex.dataField = "Sex";
dgc_sex.sortable = true;
dgc_sex.width = 90;
dg.addColumn(dgc_sex);
// 增加定义“电话”列
var dgc_phone:DataGridColumn = new DataGridColumn();
dgc_phone.editable = true;
dgc_phone.dataField = "Phone";
dgc_phone.itemEditor = cellEditor;
dgc_phone.sortable = true;
dg.addColumn(dgc_phone);
// 增加定义“QQ”列
var dgc_qq:DataGridColumn = new DataGridColumn();
dgc_qq.editable = false;
dgc_qq.dataField = "QQ";
dgc_qq.sortable = true;
dg.addColumn(dgc_qq);
// 增加定义“软件”列
var dgc_soft:DataGridColumn = new DataGridColumn();
dgc_soft.editable = false;
dgc_soft.dataField = "Software";
dgc_soft.sortable = true;
dg.addColumn(dgc_soft);
dg.dataProvider = dp;
把DataGrid组件添加到舞台中,代码如下所示:
addChild(dg);
使用DataGridCellEditor对象,定义DataGrid组件单元格的样式,代码如下所示:
/************************
* 定义单元格样式
* **********************/
private function GetCustomEditor():DataGridCellEditor
{
var dgce:DataGridCellEditor = new DataGridCellEditor();
dgce.textField.background = true;
dgce.textField.backgroundColor = 0xCC99FF;
dgce.maxChars = 2;
dgce.restrict = "1234567890";
return dgce;
}
编译代码并运行,效果如图15.6所示。
|