游戏中时常要用到DataGrid 控件来显示二维结构的数据,为了更好的展示数据,往往需要给DataGrid 控件的单元格定制更丰富的界面,比如在一个DataGrid 的某列的单元格里添加图片、文本或下拉菜单等其他下层控件,这些下层控件我们往往需要用到DataGridColumn的 itemRenderer属性,把一个定义了这些下层控件的类、类路径或一个ClassFactory对象传到这个属性里,以得到一个自定义显示界面的列。
ClassFactory和 DataGridColumn.itemRenderer 在里面的工作机制在这里不作重点介绍,需要介绍的则是如何使那些自定义的下层控件能与外界沟通,因为这些控件如果只能在定义它的类里面工作,就起不到更大的交互功能了。所以,如何让外界找到他们,会是一个很关键的环节。下面来看看我的做法:
现在有已有一个DataGrid控件dg ,为了简化说明,as代码只为dg添加了一列。自定义有一个包含了需要在DataGrid控件的某列中显示的下层控件的mxml文件: MyDgColumn.mxml,一下是dg所在的mxml文件的<Script />代码片段:
<mx:Script> …… var myDgColumn:DataGridColumn = new DataGridColumn; var myDgFactory:ClassFactory = new ClassFactory("MyDgColumn"); myDgFactory.properties = {msg:"(*^_^*)"}; myDgColumn.itemRenderer = myDgFactory; dg.columns = [myDgColumn]; …… </mx:Script>
再看看 MyDgColumn.mxml 的代码:
<?xml version="1.0" encoding="utf-8"?> <mx:LinkButton xmlns:mx="http://www.adobe.com/2006/mxml" width="30" height="20" label="按钮" click="{onClick(event)}"> <mx:Script> <![CDATA[ import mx.events.MenuEvent; public var msg:String = ""; private function onClick(event:MouseEvent):void{ trace(msg); } ]]> </mx:Script> </mx:LinkButton>
运行后点击dg列上的按钮,即可发现能够获取到 MyDgColumn.mxml 中的msg属性,这就实现了一个简单的dg与dg内部控件的交互。通过这个就可以做更复杂的代码了。这里面ClassFactory 的 properties 属性起到了很关键的作用,通过它,当ClassFactory 对象被调用了 newInstance( ) 方法,就会把properties 中相应的属性值设置给 ClassFactory将要实例花的类对象里面,以便达到同一个类生产不同对象的目的。以下是flex 中 ClassFactory的 newInstance方法的实现:
/** * Creates a new instance of the <code>generator</code> class, * with the properties specified by <code>properties</code>. * * <p>This method implements the <code>newInstance()</code> method * of the IFactory interface.</p> * * @return The new instance that was created. */ public function newInstance():* { var instance:Object = new generator(); if (properties != null) { for (var p:String in properties) { instance[p] = properties[p]; } } return instance; }