flex控制datagrid单元格可编辑

<?xml version="1.0" encoding="utf-8"?>
<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" minWidth="955" minHeight="600">
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
        import mx.events.DataGridEvent;
        import mx.events.DataGridEventReason;
        import mx.controls.TextInput;
        import mx.validators.StringValidator;
        import mx.collections.ArrayCollection;
        import mx.controls.Alert;
        
        public var nv:StringValidator;
        
        //Some data to populate the datagrid... you would probably get this from a Database in reality
        [Bindable]
        public var arData:ArrayCollection = new ArrayCollection([
        {relationship:'Friend',firstname:'Tariq',lastname:'',country:'USA'},
        {relationship:'Friend',firstname:'Jon',lastname:'Hirschi',country:'CAN'},        
        {relationship:'Boss',firstname:'Ryan',lastname:'Stewart',country:'CAN'},
        {relationship:'Family',firstname:'Mark',lastname:'Davies',country:'USA'}
        ]);
        
        //Fired when the user clicks into a datagrid cell
        private function onEditBeginning(event:DataGridEvent):void
        {
        var dataField:String = event.dataField;
        var relationship:String = dg.selectedItem.relationship;
        var country:String = dg.selectedItem.country;            
        //We only want to allow editing of friends. If it's any other relationship, stop right now.
        if(relationship!='Friend')
        {
        Alert.show('Sorry dude, you can only edit your Friends.');
        event.preventDefault();
        }
        else
        {
        //Check if this is a column we want to allow editing
        //Ya, you could do <mx:DataGridColumn editable="false" etc.../>
        //But this gives you an idea if you needed to do it conditionally based on the situation.
        if(dataField!='lastname')
        {
        Alert.show('Bro, you can only edit the last name.');
        event.preventDefault();
        }
        else
        {
        if(country!='USA')
        {
        Alert.show('You can only edit if the country is USA');
        event.preventDefault();
        }                    
        }
        }
        }        
        
        private function checkIt(myEvent:Event):void
        {
        dg.invalidateList();
        }
        
        //This gets fired when the itemEditor is about to be destroyed. As a result of hitting enter, tab, or mouse clicking away.
        private function onEditEnd(event:DataGridEvent):void
        {
        
        var dataField:String = event.dataField;
        var fCell:Array=[event.columnIndex,event.rowIndex];
        //This tells us what the new data is about to be before it's committed.
        var newData:String = TextInput(event.currentTarget.itemEditorInstance).text;
        
        nv = new StringValidator();
        
        //This if statement isn't nescessary in this example. But say you needed to validate
        //different cells differently... here's where you'd check which cell we're dealing with.
        if(dataField == 'lastname')
        {
        //specify the source - in this case the itemEditor instance
        //We only care to do this if they started typing in something
        nv.source = event.currentTarget.itemEditorInstance;
        nv.property = "text";
        nv.minLength = 3;
        nv.requiredFieldError = "at least 3 chars required";
        nv.tooShortError = "at least 3 chars required";  
    
        var val:* = nv.validate();
        if(val.type == "invalid")
        {
        event.preventDefault();
        if(newData.length!=0)
        callLater(maintainEdit,fCell); //if they typed in something and it didn't validate
        }                                  //we want to get Flex to re-invoke the editor on this cell.
        else                               //**NOTE: Once this function onEditEnd completes, the validator won't highlight
        {                                  //the cell anymore, because the itemEditor gets destroyed...
        callLater(maintainFocus);
        }
        }
        else
        callLater(maintainFocus);
        }
        
        //this checks to see if we're still in edit mode, and if we're not..invoke it
        private function maintainEdit(colIndex:int,rowIndex:int):void
        {
        var editCell:Object = {columnIndex:colIndex, rowIndex: rowIndex};
        if(dg.editedItemPosition==null)
        {
        //This will invoke the datagrid's itemEditBegin
        dg.editedItemPosition = editCell;
        //Because the itemEditor got destroyed, in the above line we're essentially creating a new itemEditor
        //So we want to invoke the validator right away so we can highlight to the user that we're not happy
        //With the validation...
        callLater(validateCurrentEditor);
        }
        }
        
        private function validateCurrentEditor():void
        {
        if(dg.itemEditorInstance!=null)
        {
        nv.source = dg.itemEditorInstance;                  
        nv.validate();
        }
        }
        
        //prevents enter/tab from moving onto the next cell after finishing editing.
        private function maintainFocus():void
        {
        dg.editedItemPosition = null;
        }
        
        ]]>
    </fx:Script>
    
    <mx:Panel title="Conditional Cell Editing Example" horizontalCenter="0" verticalCenter="0">
        <mx:Text width="300" text="This is an example of maintaining edit on the cell if validation fails,stays on the cell if the user commits via enter/tab click (but allows mouse click off the cell if the cell is empty),and only allows editing of the Last Name column if the Country is USA."/>
        <mx:DataGrid dataProvider="{arData}" height="100%" width="100%" editable="true"
                     itemEditBeginning="onEditBeginning(event)" itemEditEnd="onEditEnd(event)" id="dg" change="checkIt(event)">
            <mx:columns>
                <fx:Array>  
                    <mx:DataGridColumn dataField="relationship" headerText="Relationship"  textAlign="center"/>                                       
                    <mx:DataGridColumn dataField="firstname"         headerText="First Name"  textAlign="center"/>   
                    <mx:DataGridColumn dataField="lastname"         headerText="Last Name"  textAlign="center"/>                                 
                </fx:Array>
            </mx:columns>
        </mx:DataGrid>
        <mx:Label text="By Tariq Ahmed. www.cflex.net"/>
    </mx:Panel>
</s:Application>


你可能感兴趣的:(datagrid,function,String,Flex,application,import)