Flex3 Datagrid:标志上的自定义行

Posted

技术标签:

【中文标题】Flex3 Datagrid:标志上的自定义行【英文标题】:Flex3 Datagrid : custom rows on a flag 【发布时间】:2014-06-16 18:42:31 【问题描述】:

我正在使用具有三列的 mx 数据网格。我的 dataprovider 是一个集合 itemList ,它具有 Item 对象。项目对象有一个标志字段“isValid”。满足条件

item==null || item.isValid = false

我希望整行看起来像一个单元格(合并该行的列)并显示一个标签。这是我的网格。

        <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> 

任何想法如何做到这一点?在 SO 上找不到太多。 提前致谢。

【问题讨论】:

不幸的是,这不是Grids 的工作方式。行的每一列都有自己的ItemRenderer,由GridColumn.itemRenderer 属性定义。您可以使用GridColumn.itemRendererFunction 创建一个函数,该函数将根据行中的数据动态更改项目渲染器。所以你可以不显示一行,但你不能把一行变成一个Label 嗯,这听起来很糟糕。 【参考方案1】:

您可以模仿 3 列合并的唯一方法是使用项目渲染器。

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;
        
    

由于某种原因,您的代码没有在 actionscript3 上编译,我猜您从来没有版本,但我相信这应该可以工作。

<mx:DataGrid id="grid" dataProvider="itemList"  >   
        <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> 

专辑/年份渲染器:

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];
                
            
        

    

艺术家渲染器:

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();
            
        

    

以及我填充网格的方式:

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"));

注意:艺术家渲染器使用“神奇”数字 300 来确定 textField 的宽度,这应该使用实际的 DataGrid 宽度传递/更新,以使其扩展到完整网格的宽度。 在无效项目的艺术家文本字段下还可以看到列边框。你应该禁用边框,或者在textField 下画一个可能是白色的方块,但这是装饰工作,我相信你能够处理这些问题。

【讨论】:

以上是关于Flex3 Datagrid:标志上的自定义行的主要内容,如果未能解决你的问题,请参考以下文章

带有图像和文本的 XLForm 自定义行以及操作目标 C 上的推送控制器

尤里卡中的自定​​义行

Typeahead 在建议末尾添加自定义行

Leanback 创建不同的自定义行视图

UITableViewCell 的自定义行动画

由于 UITextView 中的自定义行距,文本选择不正确