如何在flex中自定义格式化AdvancedDataGrid中的单元格?

时间:2013-09-17 21:28:17

标签: flex

我想创建一个AdvancedDataGrid,其中一个单元格需要一些涉及图像和文本的布局工作。以下是我要解决的问题的顶级视图

(我的网格看起来像这样 - 第一列中的属性“名称”和第二列中的属性“值”

<mx:AdvancedDataGrid showHeaders="false" defaultLeafIcon="{null}">  

    <mx:columns>
        <mx:AdvancedDataGridColumn  dataField="Property" headerText="Property" backgroundColor="#E5EFF5" width="0.4" wordWrap="true"/>
        <mx:AdvancedDataGridColumn  dataField="Value" headerText="Value" backgroundColor="white" width="0.6"/>
    </mx:columns> 


</mx:AdvancedDataGrid>   

(网格的dataProvider类似于以下内容)

var retVal:ArrayCollection = new ArrayCollection([

{Property:'AA', Value:1},
{Property:'BB',  Value: <Object that requires custom formatting when displayed in the grid>},                                                          
{Property:'CC',  Value:"Simple string"}
                                                         ]);

单独的属性BB具有更复杂的视图,涉及在特定布局中布置图像和文本。每个其他属性都有一个简单的字符串或数字值,不需要任何特殊格式。

像itemRenderer这样的东西被证明对我来说太难了,因为在网格内显示时,并非所有给定列的列条目都以相同的方式格式化。

我使用的是AdvancedDataGrid,因为它在网格中提供类似导航的树(使用子节点),这是我最终需要的东西。

一个例子会有所帮助,因为我是flex的新手。

谢谢。


我试图创建一个例子而它没有做我想要的事情

// GridExample.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<fx:Script>


    <![CDATA[
        import mx.collections.ArrayCollection;



        [Bindable]
        var data:ArrayCollection = new ArrayCollection([{Property:'AA', RowIdentifier: "SimpleType", Value:3},
                                                        {Property:'BB', RowIdentifier: "ArrayType", Value:["one", "two", "three"]}, 
                                                        {Property:'CC',  RowIdentifier: "SimpleType", Value:"My string"}
                                                        ]);

    ]]>
</fx:Script>

<mx:Box height="300" width="300">

    <mx:AdvancedDataGrid  
                         variableRowHeight="true"
                         width="100%"
                         showHeaders="false" 
                         defaultLeafIcon="{null}"
                         dataProvider="{data}">  


        <mx:columns>
            <mx:AdvancedDataGridColumn  dataField="Property" headerText="Property" backgroundColor="#E5EFF5" width="0.4" wordWrap="true"/>
            <mx:AdvancedDataGridColumn  dataField="Value" headerText="Value" backgroundColor="white" width="0.6" itemRenderer="ExampleRenderer"/>
            <mx:AdvancedDataGridColumn  dataField="RowIdentifier" visible="false"/>
        </mx:columns> 


    </mx:AdvancedDataGrid>      

</mx:Box>

</s:WindowedApplication>

// ExampleRenderer.mxml     

<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" textAlign="center"    creationComplete="renderNow()" >
<mx:Script>
    <![CDATA[

        import mx.containers.HBox;
        import mx.containers.VBox;
        import mx.controls.Alert;
        import mx.controls.Image;
        import mx.controls.Label;
        import mx.resources.ResourceManager;

        private var dataObject:Object;



        private function renderNow():void {

            var rowId:String = dataObject["RowIdentifier"];
            if (rowId == "ArrayType"){
                var valueObj:Array = dataObject["Value"];
                var vBox:VBox = new VBox();
                vBox.percentHeight = 100;
                vBox.percentWidth = 100;


                for (var i:uint=0; i<valueObj.length;i++){
                    //Create the hBoxes that will wrap the host icon and the host Ip                    
                    var hBox:HBox = new HBox();

                    //Add host icon to the box
                    var imageIcon:Image = new Image();
                    imageIcon.source = "@Embed(source='adobe.png')";
                    hBox.addChild(imageIcon);


                    //Appears to the right
                    var label2:Label = new Label();
                    label2.text = valueObj[i];
                    label2.percentHeight = 100;
                    label2.percentWidth = 70;
                    hBox.addChild(label2);

                    //Add the hBox to the vBox
                    vBox.addChild(hBox);                    
                }
                this.addChild(vBox);
            }
            else{
                var iLabel:Label = new Label();
                iLabel.text = dataObject["Value"];
                iLabel.percentHeight = 100;
                iLabel.percentWidth = 100;
                this.addChild(iLabel);
            }
        }

        override public function set data(value:Object):void
        {
            dataObject = value;
        }
    ]]>
</mx:Script>

</mx:Box>

运行它的输出给了我错误的网格单元格(属性值完全关闭,当我尝试调整大小时,如果我的Box宽度和高度设置为百分比,它们会四处运行)

你能帮我找到我在做什么的错吗?任何帮助表示赞赏。

此致

1 个答案:

答案 0 :(得分:1)

项目渲染器被回收,这意味着您应该期望可以随机地从列表中为任何一个渲染器实例分配数据项(例如,数据设置器应该驱动任何视觉变化)。不要忘记重置其他数据项上任何先前渲染的状态。

<fx:Script>


    <![CDATA[
        import mx.collections.ArrayCollection;

        [Bindable]
        private var _data:ArrayCollection =
            new ArrayCollection([{Property: 'AA', RowIdentifier: "SimpleType", Value: 3},
            {Property: 'BB', RowIdentifier: "ArrayType", Value: ["one", "two", "three"]},
            {Property: 'CC', RowIdentifier: "SimpleType", Value: "My string"}]);
    ]]>
</fx:Script>

<mx:Box width="300" height="300">

    <mx:AdvancedDataGrid width="100%" dataProvider="{_data}" defaultLeafIcon="{null}" showHeaders="false"
                         variableRowHeight="true">
        <mx:columns>
            <mx:AdvancedDataGridColumn width="0.4" backgroundColor="#E5EFF5" dataField="Property"
                                       headerText="Property" wordWrap="true" />
            <mx:AdvancedDataGridColumn width="0.6" backgroundColor="white" dataField="Value" headerText="Value">
                <mx:itemRenderer>
                    <fx:Component>
                        <s:MXAdvancedDataGridItemRenderer>

                            <fx:Script>
                                <![CDATA[
                                    import mx.containers.HBox;
                                    import mx.containers.VBox;
                                    import mx.controls.Image;
                                    import mx.controls.Label;

                                    override public function set data(value:Object):void
                                    {
                                        super.data = value;

                                        renderNow(value);
                                    }

                                    private function renderNow(data:Object):void
                                    {

                                        //remove any components added from a different data item
                                        this.removeAllElements();

                                        var rowId:String = data["RowIdentifier"];

                                        if(rowId == "ArrayType")
                                        {
                                            var valueObj:Array = data["Value"];
                                            var vBox:VBox = new VBox();
                                            vBox.percentHeight = 100;
                                            vBox.percentWidth = 100;

                                            for(var i:uint = 0; i < valueObj.length; i++)
                                            {
                                                //Create the hBoxes that will wrap the host icon and the host Ip                    
                                                var hBox:HBox = new HBox();

                                                //Add host icon to the box
                                                var imageIcon:Image = new Image();
                                                imageIcon.source = "@Embed(source='adobe.png')";
                                                hBox.addChild(imageIcon);

                                                //Appears to the right
                                                var label2:Label = new Label();
                                                label2.text = valueObj[i];
                                                label2.percentHeight = 100;
                                                label2.percentWidth = 70;
                                                hBox.addChild(label2);

                                                //Add the hBox to the vBox
                                                vBox.addChild(hBox);
                                            }
                                            this.addElement(vBox);
                                        }
                                        else
                                        {
                                            var iLabel:Label = new Label();
                                            iLabel.text = data["Value"];
                                            iLabel.percentHeight = 100;
                                            iLabel.percentWidth = 100;
                                            this.addElement(iLabel);
                                        }
                                    }
                                ]]>
                            </fx:Script>

                        </s:MXAdvancedDataGridItemRenderer>
                    </fx:Component>
                </mx:itemRenderer>
            </mx:AdvancedDataGridColumn>
            <mx:AdvancedDataGridColumn dataField="RowIdentifier" visible="false" />
        </mx:columns>
    </mx:AdvancedDataGrid>

</mx:Box>