Understanding Flex itemEditors

http://www.adobe.com/devnet/flex/articles/itemeditors_pt1.html 

 http://www.adobe.com/devnet/flex/articles/itemeditors_pt2.html

http://www.adobe.com/devnet/flex/articles/itemeditors_pt3.html 

     我最近完成了itemRenderes系列文章---自定义list控件中内容的的显示样式。Displaying和rendering content是非常有效的UI技术,使用Flex,你可以做你能想像到的任何事情。

      文章的第一步分涉及itemEditor。使用itemEditor可在控件上直接改变数据。第一篇文章涵盖了inline itemEditor。它是一种简单有效的组件,可直接在MXML中定义。后面的文章涵盖了更复杂的itemEditor,validation,事件和itemRenders as itemEditors。

文本输入编辑框

     直接在list控件上编辑是很方便的。想像一个仓库清单DataGrid控件。你可以使用它校正其内容,无须一个弹出式窗体。list控件有一个内建的文本编辑控件。当用户单击可编辑区域时,它就出现在用户单击的地方。可编辑区域可以是行(List控件),可以是分支(Tree控件),可以是格子(DataGrid)。你要将list控件的editable属性设为true。对于DataGrid控件你可以设置DataGridColumn的editable属性为false来关闭其编辑功能。

 

                           图片1 itemEditors允许直接在DataGrid上编辑

    itemEditor不同于itemRender的地方仅在于实例化一个itemEditor后,仅在编辑它时,它才可见。itemEditor不可见直到一个可编辑的cell得到了输入焦点。 接着itemRender被隐藏,itemEditor移动到点击的位置,尺寸与那个cell相同,并为记录数据。当编辑结束时(移动焦点到其它位置),list控件从itemEidtor中复制数据到dataProvider记录中。

   在图1所示的程序中,当用户点击"Part#"行的格子时,dataProvider[row][dataField]的值被赋给ItemEditor(TextInput)控件的文件属性。当编辑结束时,复制itemEditor(TextInput)控件的文本属性到dataProvider[row][dataField]中。dataProvider,是一个集合, dispatches an event in response to the update.

    当默认的TextInput控件为editor时,它只适用于大多数简单的例子中。它采用String,如书名,作者名或产品名。如果你需要更多的控件或想检查用户的输入,那么你要自己亲自去做。

Flex itemEditors控件

这里告诉你做一个处理数值的itemEditor: 

 <mx:DataGrid x="46" y="270" editable="true" dataProvider="{employeeDB}">

     <mx:columns>
          <mx:DataGridColumn headerText="Name" dataField="name"/>
          <mx:DataGridColumn headerText="Position" dataField="position"/>
          <mx:DataGridColumn headerText="Age" dataField="age">
               <mx:itemEditor>
                    <mx:Component>
                         <mx:TextInput restrict="0-9" maxChars="3" />
                    </mx:Component>
               </mx:itemEditor> 
          </mx:DataGridColumn>
     </mx:columns>
</mx:DataGrid>

<me>

修改代码 使用flex4.6编译

<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkDGSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s
="library://ns.adobe.com/flex/spark"
xmlns:mx
="library://ns.adobe.com/flex/mx">
    <fx:Script>
    <![CDATA[      
        import mx.collections.*;
        [Bindable]
        private var employeeDB:ArrayCollection = new ArrayCollection(
            [ {name:"James Kirk", position:"Captain", age:38},
              {name:"Spock", position:"1st Officer", age:154},
              {name:"Montgomery Scott", position:"Engineer (Chief)", age: 46},
              {name:"Leonard McCoy", position:"Doctor", age: 52}
            ]);
    
]]>
    </fx:Script>
    <mx:DataGrid x="46" y="270" editable="true" dataProvider="{employeeDB}">
         <mx:columns>
              <mx:DataGridColumn headerText="Name" dataField="name"/>
              <mx:DataGridColumn headerText="Position" dataField="position"/>
              <mx:DataGridColumn headerText="Age" dataField="age">
                   <mx:itemEditor>
                        <fx:Component>
                             <mx:TextInput restrict="0-9" maxChars="3" />
                        </fx:Component>
                   </mx:itemEditor> 
              </mx:DataGridColumn>
         </mx:columns>
    </mx:DataGrid>

</s:Application>

运行 

</me> 

 restrict和maxChars属性保证age值在三个数字之内。

<meCheckBox/> 

CheckBox是itemEditor的另一种常见的控件。它可以编辑Boolean值。图2中显示了使用CheckBox的例子。此例中CheckBox编辑货物清单的In Stock列的值。 

 

<me>

 <?xml version="1.0" encoding="utf-8"?>

<!-- dpcontrols\sparkdpcontrols\SparkDGSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s
="library://ns.adobe.com/flex/spark"
xmlns:mx
="library://ns.adobe.com/flex/mx">
    <fx:Script>
    <![CDATA[      
        import mx.collections.*;
        [Bindable]
        private var inventoryDB:ArrayCollection = new ArrayCollection(
            [ {product:"Widgets", part:"WDG-1000", inStock:true, quantity: 53},
              {product:"Gizmos", part:"GZM-850", inStock:false, quantity: 0},
              {product:"Thingys", part:"THG-4320", inStock:true, quantity: 120},
              {product:"Gadgets", part:"GAT-910", inStock:true, quantity: 4}
            ]);
         private function inStockLabeler( item:Object, col:* ) : String
        {
            return item.inStock ? "yes" : "NO";
        }
    
]]>
    </fx:Script>
<mx:DataGrid x="531" y="273" editable="true" dataProvider="{inventoryDB}">
     <mx:columns>
          <mx:DataGridColumn headerText="Product" dataField="product"/>
          <mx:DataGridColumn headerText="Part #" dataField="part"/>
          <mx:DataGridColumn headerText="In Stock?" dataField="inStock"
               labelFunction
="inStockLabeler"
               itemEditor
="mx.controls.CheckBox" editorDataField="selected" /> 
           <mx:DataGridColumn headerText="Quantity" dataField="quantity"/>
     </mx:columns>
</mx:DataGrid>
</s:Application>

 运行

</me> 

在这个例子中,列中格子的内容由labelFunction(inStockLabeler)函数渲染。此函数可以显示Yes或NO。属性itemEditor设置为mx.controls.CheckBox类. 另一个重要的的事情,是设置DataGridColumn: editorDataField 的属性值。editorDataField 属性指定用来接收值的itemEditor属性,当编辑结束时。当编辑结束时,DataGrid将使用selected属性,代替数据集中的inStock属性。

此时,你可能明白了为什么TextInput的那个例子没有提供editorDataField属性。因为editorDataField默认的属性是"text"。刚好是TextInput控件保存输入数据的属性的名字。

你可以在Flexnumber控件上使用同样的技术。这里有一个使用NumericStepper的例子。如图3所示。

 

<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkDGSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s
="library://ns.adobe.com/flex/spark"
xmlns:mx
="library://ns.adobe.com/flex/mx">
    <fx:Script>
    <![CDATA[      
        import mx.collections.*;
        [Bindable]
        private var inventoryDB:ArrayCollection = new ArrayCollection(
            [ {product:"Widgets", part:"WDG-1000", inStock:true, quantity: 53},
              {product:"Gizmos", part:"GZM-850", inStock:false, quantity: 0},
              {product:"Thingys", part:"THG-4320", inStock:true, quantity: 120},
              {product:"Gadgets", part:"GAT-910", inStock:true, quantity: 4}
            ]);
    
]]>
    </fx:Script>
<mx:DataGrid x="531" y="273" editable="true" dataProvider="{inventoryDB}">
     <mx:columns>
          <mx:DataGridColumn headerText="Product" dataField="product"/>
          <mx:DataGridColumn headerText="Part #" dataField="part"/>
          <mx:DataGridColumn headerText="In Stock?" dataField="inStock"/> 
           <mx:DataGridColumn headerText="Quantity" dataField="quantity"  
                itemEditor
="mx.controls.NumericStepper" editorDataField="value"/>
     </mx:columns>
</mx:DataGrid>
</s:Application>

 

运行

注意 editorDataField 为"value"。它是NumericStepper的属性。NumericStepper用它保存当前控件的值。你要确保itemEditor使用的类完全正确。否则编译器不会找个这个类,它会报错。

一个复杂点的Editor

现在假定你要做一点复杂的事情。Flex没有对应的控件。 此例允许用户使用四个数字输入框输入一个信用卡号。

 <?xml version="1.0" encoding="utf-8"?>

<!-- dpcontrols\sparkdpcontrols\SparkDGSimple.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s
="library://ns.adobe.com/flex/spark"
xmlns:mx
="library://ns.adobe.com/flex/mx">
    <fx:Script>
    <![CDATA[      
        import mx.collections.*;
        [Bindable]
        private var accountDB:ArrayCollection = new ArrayCollection(
            [ {account:"John's Pants",  ccard:"1234100012341000"},
              {account:"Jeopardy Airlines", ccard:"0000222244441111"},
              {account:"No-Go Adventures", ccard:"9222833374446555"}
            ]);
    
]]>
    </fx:Script>
<mx:DataGrid x="46" y="463" editable="true" dataProvider="{accountDB}" width="302">
     <mx:columns>
          <mx:DataGridColumn headerText="Account" dataField="account" width="100"/>
          <mx:DataGridColumn headerText="Credit Card" dataField="ccard" editorDataField="value">
               <mx:itemEditor>
                    <fx:Component>
                         <mx:HBox>
                              <fx:Script>
                                   <![CDATA[
                                        public function get value() : String
                                        {
                                             return part1.text+part2.text+part3.text+part4.text;
                                        }
                                        override public function set data(value:Object):void
                                        {
                                             super.data = value;
                                             part1.text = value.ccard.substr(0,4);
                                             part2.text = value.ccard.substr(4,4);
                                             part3.text = value.ccard.substr(8,4);
                                             part4.text = value.ccard.substr(12,4);
                                        }
                                   
]]>
                              </fx:Script>
                              <mx:TextInput id="part1" maxChars="4" restrict="0-9" width="40" />
                              <mx:TextInput id="part2" maxChars="4" restrict="0-9" width="40" />
                              <mx:TextInput id="part3" maxChars="4" restrict="0-9" width="40" />
                              <mx:TextInput id="part4" maxChars="4" restrict="0-9" width="40" />
                         </mx:HBox>
                    </fx:Component>
               </mx:itemEditor>
          </mx:DataGridColumn>
     </mx:columns>
</mx:DataGrid>
</s:Application>

运行

 

posted @ 2012-06-04 20:56  thinkpore  阅读(170)  评论(0)    收藏  举报