简体   繁体   中英

Flex3 Datagrid : custom rows on a flag

I am using an mx datagrid with three columns. My dataprovider is a collection, itemList which has Item objects. Item object has a flag field 'isValid'. On meeting the condition

item==null || item.isValid = false

I want the entire row to look like a single cell (merge the columns for the row) and display a label. Here is my grid.

        <mx:DataGrid id="grid" dataProvider="{itemList}">   
        <mx:columns>
            <mx:ArrayList>
                <mx:GridColumn dataField="Artist" headerText="Artist"/>
                <mx:GridColumn dataField="Album" headerText="Album"/>
                <mx:GridColumn dataField="Year" headerText="Year"/>
            </mx:ArrayList>
        </mx:columns>       
    </mx:DataGrid> 

Any ideas how to do it? Couldn't find much on SO. Thanks in advance.

The only way you could mimic 3 column merge, would be with item renderers.

package
{
    public class Item
    {
        public var Artist:String;
        public var Album:String;
        public var Year:String;
        public var isValid:Boolean;

        public function Item(artist:String, album:String, year:String, isValid:Boolean = true)
        {
            this.Artist = artist;
            this.Album = album;
            this.Year = year;
            this.isValid = isValid;
        }
    }
}

For some reason your code didn't compile on actionscript3, I guess you have never version, but I believe this should work.

<mx:DataGrid id="grid" dataProvider="{itemList}" width="100%" height="100%">   
        <mx:columns>
            <mx:DataGridColumn id="artist" dataField="Artist" headerText="Artist"/>
            <mx:DataGridColumn id="album" dataField="Album" headerText="Album"/>
            <mx:DataGridColumn id="year" dataField="Year" headerText="Year"/>
        </mx:columns>       
</mx:DataGrid> 

Album/Year renderer:

package
{
    import mx.containers.HBox;
    import mx.controls.Label;
    import mx.controls.listClasses.IListItemRenderer;

    public class AlbumYearItemRenderer extends HBox implements IListItemRenderer
    {
        public var dataField:String;

        private var labelComponent:Label;
        private var _itemChanged:Boolean;
        private var _data:Item;

        override public function set data(data:Object):void
        {
            super.data = data;
            _data = data as Item;
            _itemChanged = true;
        }

        protected override function createChildren():void
        {
            super.createChildren();

            labelComponent = new Label();
            removeAllChildren();
            addChild(labelComponent);
        }


        protected override function commitProperties():void
        {
            super.commitProperties();

            if(_itemChanged)
            {
                _itemChanged = false;

                if((_data as Item).isValid)
                {
                    labelComponent.text = _data[dataField];
                }
            }
        }

    }
}

Artist renderer:

package
{
    import flash.display.BitmapData;
    import flash.text.TextField;

    import mx.containers.Canvas;
    import mx.controls.Label;
    import mx.controls.listClasses.IListItemRenderer;
    import mx.core.UIComponent;

    public class ArtistRenderer extends Canvas implements IListItemRenderer
    {

        private var c:UIComponent;
        private var labelField:Label;
        private var textField:TextField;
        private var _itemChanged:Boolean;
        private var _data:Item;
        private var labelImage:BitmapData;

        override public function set data(data:Object):void
        {
            super.data = data;
            _data = data as Item;
            _itemChanged = true;
        }

        protected override function createChildren():void
        {
            super.createChildren();

            labelField = new Label();
            textField = new TextField();
            c = new UIComponent();

            removeAllChildren();
        }


        protected override function commitProperties():void
        {
            super.commitProperties();

            if(_itemChanged)
            {
                _itemChanged = false;

                if(_data.isValid)
                {
                    labelField.text = _data.Artist;
                    addChild(labelField);
                }
                else
                {
                    textField.text = _data.Artist;
                    textField.width = 300;
                    labelImage = new BitmapData(textField.width, textField.height, true, 0x000000ff);
                    labelImage.draw(textField);
                }
            }
        }

        protected override function measure():void
        {
            super.measure();

            if(!_data.isValid && labelImage != null)
            {
                graphics.beginBitmapFill(labelImage);
                graphics.drawRect(0, 0, textField.width, textField.height);
                graphics.endFill();
            }
        }

    }
}

and the way I fill grid:

protected function init():void
{
    var rend1:ClassFactory = new ClassFactory(ArtistRenderer);
    artist.itemRenderer = rend1;

    var rend2:ClassFactory = new ClassFactory(AlbumYearItemRenderer);
    rend2.properties = {dataField: album.dataField};
    album.itemRenderer = rend2;

    var rend3:ClassFactory = new ClassFactory(AlbumYearItemRenderer);
    rend3.properties = {dataField: year.dataField};
    year.itemRenderer = rend3;


    itemList.addItem(new Item("artist1", "album1", "year1"));
    itemList.addItem(new Item("artist1", "album2", "year1"));
    itemList.addItem(new Item("artist2......................INVALID!", "album1", "year1", false));
    itemList.addItem(new Item("artist2", "album1", "year2"));
}

NOTE: Artist renderer uses "magical" number 300 to determine textField 's width, this should be passed/updated with actual DataGrid 's width to make it expand to full grid's width. Also column borders are seen under an invalid item's artist textField. You should either disable borders or draw a maybe white square under textField , but it's cosmetic job and I believe you will be able to dealt with this stuff.

样本图片

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM