在DataGrid中使用itemRender和itemEditor,综合应用一例

功能描述
在DataGrid中,综合使用一些组件,包括RadioButtonGroup、checkbox、ComboBox等

技术点说明
  • itemRender和itemEditor的用法
  • renderIsEditor = true,可以始终显示Editor
  • 将多种不同格式的日期字符串使用正则表达式转换成日期类型,默认不能直接将yyyy-mm-dd格式直接转换成日期
  • 工资账号分组编辑
  • 复选框(CheckBox)、单选框(RadioButtonGroup)、下拉列表框(ComboBox)的用法
  • 日期选择(DateField),出生日期使用 renderIsEditor
更多的细节可以直接看代码中的注释

预览


代码下载
baseUsing.mxml
http://my.jhost.cn/iihe602_2/flex/sdk3/baseUsing.html

执行效果
 

代码展示
  1 <?xml version="1.0" encoding="utf-8"?>
  2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left"
  3     fontSize="12" borderColor="white"> 
  4 
  5     <mx:Script>
  6         <![CDATA[
  7             import mx.events.DataGridEventReason;
  8             import mx.events.DataGridEvent;
  9             import mx.controls.Alert;
 10             import mx.events.CollectionEvent;
 11             import mx.charts.chartClasses.DataDescription;
 12             import mx.utils.StringUtil; 
 13             import mx.utils.ArrayUtil;
 14 
 15             import mx.formatters.DateFormatter;  
 16             
 17             [Bindable]
 18             public var cities: Array =& amp;nbsp;("北京,天津,河北,内蒙古,山西,上海,安徽,江苏,浙江,山东,福建,江西,广东,广西,海 南," + 
 19                     " 河南,湖北,湖南,黑龙江,吉林,辽宁,陕西,甘肃,宁夏,青海,XinJiang,重庆,四川,云南,贵州,西藏,香港,澳门,台 湾").split(",");
 20 
 21             private function birthday_labelFunction(item:Object, column:DataGridColumn):String
 22             {
 23                 //return birthdayFormatter.format(item.birthday);  这样些,得到的是一个空值,必须使用toString(),这一点需要注意
 24                 // 下面的方法才正确
 25                 return birthdayFormatter.format(item.birthday.toString());
 26             }
 27             
 28             private function age_labelFunction(item:Object, column:DataGridColumn):String
 29             {
 30                 // todo:  将类似1999-2-24这样的字符串解析成日期,会有不成功的情况,暂时先使用正则表达式匹配获取到年
 31                 // 下面的方法才正确
 32                 var birthStr: String = item.birthday.toString().match(/\d{4}/);
 33                 var now: Date = new Date();
 34                 return (now.fullYear - Number(birthStr)).toString();
 35             }
 36             
 37             private function married_labelFunction(item:Object, column:DataGridColumn):String
 38             {
 39                 return item.married ==& amp;nbsp;"已婚" ? "已婚" : "未婚";
 40             }    
 41             
 42             protected function dg_itemEditEndHandler(event:DataGridEvent):void
 43             {
 44                 // 如果用户按Cancel键,则不需要处理
 45                 if (event.reason == DataGridEventReason.CANCELLED) return;
 46                 
 47                 // 是否正在输入birthday
 48                 if (event.dataField == "birthday")
 49                 {
 50 //                     //注意是怎么获取当前输入组件实例
 51 //                    var editor: TextInput = (event.target as DataGrid).itemEditorInstance as TextInput;
 52 //                     //检查日期是否合法
 53 //                     // todo: 目前还没有判断日期是否真正合法?
 54 //                    if (editor.text.search(/(\d{4})-(\d{1,2})-(\d{1,2})/) == -1)
 55 //                    {
 56 //                         //阻止将输入值提交到后台
 57 //                        event.preventDefault();
 58 //                         //显示错误提示信息
 59 //                        editor.errorString =& amp;nbsp;"日期输入错误。";
 60 //                    }
 61                 }
 62                 // 还可以继续判断其他列的输入
 63             }
 64 
 65         ]]>
 66     </mx:Script>
 67 
 68     <mx:DateFormatter id="birthdayFormatter" formatString="YYYY-MM-DD"/>
 69 
 70     <mx:XML id="employees" source="assets/data.xml"/>
 71     
 72     <mx:XMLListCollection id="employeeCollection" source="{employees.emp}"/>
 73     
 74     <mx:DataGrid id="dg" dataProvider="{employeeCollection}" editable="true" tabChildren="true"
 75         itemEditEnd="dg_itemEditEndHandler(event)">
 76         <mx:columns>
 77             <mx:DataGridColumn headerText="员工编号" dataField="empId" editable="false" color="gray"/>
 78             
 79             <mx:DataGridColumn headerText="姓名" dataField="name"/>
 80             
 81             <!--使用RadioButtonGroup-->
 82             <mx:DataGridColumn headerText="性别" dataField="sex" width="100" editorDataField="value" rendererIsEditor="true">
 83                 <mx:itemRenderer>
 84                     <mx:Component>
 85                         <mx:HBox>
 86                             <mx:Script>
 87                                 <![CDATA[
 88                                     import mx.controls.DateField;
 89                                     public function get value(): Object
 90                                     {
 91                                         return sexGroup.selectedValue;
 92                                     }
 93                                     
 94                                     override public function set data(value:Object) : void
 95                                     {
 96                                         super.data = value;
 97                                         sexGroup.selectedValue = value.sex;
 98                                         
 99                                     } 
100                                 ]]>
101                             </mx:Script>
102                             <mx:RadioButtonGroup id="sexGroup"/>
103                             <mx:RadioButton groupName="sexGroup" label="男" value="男"/>
104                             <mx:RadioButton groupName="sexGroup" label="女" value="女"/>
105                         </mx:HBox>
106                     </mx:Component>
107                 </mx:itemRenderer>
108             </mx:DataGridColumn>
109             
110             <mx:DataGridColumn headerText="出生日期" dataField="birthday" editorDataField="value" rendererIsEditor="true">
111                 <mx:itemRenderer>
112                     <mx:Component>
113                         <mx:Box>
114                             <mx:Script>
115                                 <![CDATA[
116                                     public function get value(): Object
117                                     {
118                                         /* 注意:月份是从0开始的,所以必须加1*/
119                                         return df.selectedDate.fullYear.toString() + "/" + (df.selectedDate.month+1).toString() + "/" + df.selectedDate.date.toString();
120                                     }
121                                     
122                                     override public function set data(value:Object) : void
123                                     {
124                                         super.data = value;
125                                         var datestr: String = value.birthday.toString();
126                                         var tempDate:Date = null;
127                                         var re:RegExp = null;
128                                         
129                                         /*yyyy-mm-dd*/
130                                         re = /(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})/;
131                                         if (tempDate == null && re.test(datestr))
132                                         {                                         
133                                             datestr = datestr..replace(re, "$1/$2/$3");
134                                             tempDate = new Date(datestr);
135                                         }
136                                         
137                                         /* mm-dd-yyyy */
138                                         re = /(\d{1,2})[-\/](\d{1,2})[-\/](\d{4})/;
139                                         if (tempDate == null && re.test(datestr))
140                                         {
141                                             datestr = datestr..replace(re, "$3/$1/$2");
142                                             tempDate = new Date(datestr);
143                                         }
144                                         
145                                         if (tempDate != null)
146                                             df.selectedDate = tempDate;
147                                     }
148                                 ]]>
149                             </mx:Script>
150                             <mx:DateField id="df" width="100%" formatString="YYYY-MM-DD"/>
151                         </mx:Box>
152                     </mx:Component>
153                 </mx:itemRenderer>
154             </mx:DataGridColumn>
155             
156             <!--注意不同日期格式转换成日期类型的算法,由于as默认并不支持将yyyy-mm-dd中国常用的日期格式直接转换成日期类 型,
157                    因此这里使用正则表达式进行匹配并转换-->
158             <mx:DataGridColumn headerText="年龄(计算)" dataField="age" editable="false" labelFunction="age_labelFunction" color="gray"/>
159             
160             <mx:DataGridColumn headerText="籍贯" dataField="city" editorDataField="value">
161                 <mx:itemEditor>
162                     <mx:Component>
163                         <mx:HBox>
164                             <mx:Script>
165                                 <![CDATA[
166                                     import mx.utils.ArrayUtil;
167                                     
168                                     public function get value(): Object
169                                     {
170                                         // 由于HBox不能够直接返回value,需要写一个value的getter函数
171                                         return citiesComboBox.selectedItem;
172                                     }
173                                     
174                                     override public function set data(value:Object) : void
175                                     {
176                                         // 必须要给data复制,否则会导致程序崩溃
177                                         super.data = value;
178                                         // 给combobox赋初始值
179                                         citiesComboBox.selectedItem = value.city;
180                                     } 
181                                 ]]>
182                             </mx:Script>
183                             <mx:ComboBox id="citiesComboBox" dataProvider="{ArrayUtil.toArray(outerDocument.cities)}" width="100%"/>
184                         </mx:HBox>
185                     </mx:Component>
186                 </mx:itemEditor>
187             </mx:DataGridColumn>
188             
189             <!--在表格中使用checkbox,注意是如何将实际数据和显示数据进行转换的-->
190             <mx:DataGridColumn headerText="婚否" dataField="married" editorDataField="value" rendererIsEditor="true">
191                 <mx:itemRenderer>
192                     <mx:Component>
193                         <mx:Box horizontalAlign="center">
194                             <mx:Script>
195                                 <![CDATA[
196                                     public function get value(): Object
197                                     {
198                                         return cbMarried.selected ? " 已婚" : "未 婚";                                    
199                                     }
200                                     
201                                     override public function set data(value:Object) : void
202                                     {
203                                         super.data = value;
204                                         cbMarried.selected =& amp;nbsp;value.married == "已婚";  & amp;nbsp;                                 
205                                     }
206                                 ]]>
207                             </mx:Script>
208                             <mx:CheckBox id="cbMarried"/>
209                         </mx:Box>        
210                     </mx:Component>
211                 </mx:itemRenderer>
212             </mx:DataGridColumn>
213             
214             <!--将工资账号进行4位一组,便于输入;显示时也是4位一组,便于阅读;但实际存储是连续 的-->
215             <mx:DataGridColumn headerText="工资账号" dataField="salaryBankId" width="240" editorDataField="value">
216                 <mx:itemRenderer>
217                     <mx:Component>
218                         <mx:HBox>
219                             <mx:Script>
220                                 <![CDATA[
221                                     override public function set data(value:Object) : void
222                                     {
223                                         super.data = value;
224                                         // 为了便于查看,进行了4位分组,实际存储仍然是连续的
225                                         p1.text =   value.salaryBankId.toString().substr(0, 4)
226                                             + " " + value.salaryBankId.toString().substr(4, 4)
227                                             + " " + value.salaryBankId.toString().substr(8, 4)
228                                             + " " + value.salaryBankId.toString().substr(12, 4);
229                                     }
230                                 ]]>
231                             </mx:Script>
232                             <mx:Label id="p1"/>
233                         </mx:HBox>
234                     </mx:Component>
235                 </mx:itemRenderer>
236                 <mx:itemEditor>
237                     <mx:Component>
238                         <mx:HBox tabChildren="true">
239                             <mx:Script>
240                                 <![CDATA[
241                                     import mx.managers.FocusManager;
242                                     // 从编辑组件获取输入值时被执行,这个函数的名称和editorDataField是对应的
243                                     public function get value(): Object
244                                     {
245                                         return p1.text + p2.text + p3.text + p4.text;
246                                     }
247                                     
248                                     //listitem 把数据赋值给编辑组件时,被执行
249                                     override public function set data(value:Object) : void
250                                     {
251                                         super.data = value;
252                                         p1.text = value.salaryBankId.toString().substr(0, 4);
253                                         p2.text = value.salaryBankId.toString().substr(4, 4);
254                                         p3.text = value.salaryBankId.toString().substr(8, 4);
255                                         p4.text = value.salaryBankId.toString().substr(12, 4);
256                                     }
257                                     
258                                     // todo:  在多个输入框之间切换焦点,现在的情况是按tab键,焦点移动到了下一个单元格
259                                     //  这里tab好像是被DataGrid强行占用,不起作用,始终是按系统默认执行
260                                     //  采取的方法:
261                                     //         在一个文本框上输入完成后,自动跳到下一个输入框
262                                     //         按左右箭进行各输入框之间进行切换
263                                     protected function internal_keyDownHandler(event:KeyboardEvent, previousText: TextInput, nextText: TextInput):void
264                                     {
265                                         if (event.target.selectionBeginIndex == 4 && event.target.selectionEndIndex == 4 && event.keyCode != Keyboard.LEFT)
266                                         {
267                                             if (nextText != null)
268                                             {
269                                                 nextText.setFocus();
270                                                 nextText.selectionBeginIndex = 0;
271                                                 nextText.selectionEndIndex = 4;
272                                                 
273                                             }
274                                         }
275                                         else if (event.target.selectionBeginIndex == 0 && event.target.selectionEndIndex == 0 && event.keyCode == Keyboard.LEFT)
276                                         {
277                                             if (previousText != null)
278                                             {
279                                                 previousText.setFocus();
280                                                 previousText.selectionBeginIndex = 0;
281                                                 previousText.selectionEndIndex = 4;
282                                             }
283                                         }
284                                     }
285 
286                                 ]]>
287                             </mx:Script>
288                             <mx:TextInput id="p1" width="45" maxChars="4" restrict="0-9" keyDown="internal_keyDownHandler(event, null, p2)"/>
289                             <mx:TextInput id="p2" width="45" maxChars="4" restrict="0-9" keyDown="internal_keyDownHandler(event, p1, p3)"/>
290                             <mx:TextInput id="p3" width="45" maxChars="4" restrict="0-9" keyDown="internal_keyDownHandler(event, p2, p4)"/>
291                             <mx:TextInput id="p4" width="45" maxChars="4" restrict="0-9" keyDown="internal_keyDownHandler(event, p3, null)"/>
292                         </mx:HBox>
293                     </mx:Component>
294                 </mx:itemEditor>
295             </mx:DataGridColumn>
296         </mx:columns>
297     </mx:DataGrid>
298     
299     <mx:Button label="显示XML数据">
300         <mx:click>
301             <![CDATA[
302                 employeesAsStr.text = employeeCollection.toXMLString();
303             ]]>
304         </mx:click>
305     </mx:Button>
306     
307     <!--直接将employeeCollection与text绑定,并不起作用,目前还没有分析出来是什么原 因-->
308     <mx:TextArea id="employeesAsStr" text="{employeeCollection}" width="{dg.width}" height="250"/>
309     
310 </mx:Application>
311 
posted @ 2009-09-24 21:51  静候良机  阅读(1856)  评论(1编辑  收藏  举报