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

Apache flex 如何在flex中自定义AdvancedDataGrid中的单元格格式?,apache-flex,Apache Flex,我想创建一个AdvancedDataGrid,其中一个单元格需要一些涉及图像和文本的布局工作。下面是我试图解决的问题的顶层视图 (我的网格看起来像这样-第一列中的属性“name”,第二列中的属性“value”) (网格的数据提供程序如下所示) var retVal:ArrayCollection=新的ArrayCollection([ {属性:'AA',值:1}, {属性:'BB',值:}, {属性:'CC',值:“简单字符串”} ]); 仅属性BB就有一个更复杂的视图,涉及在特定布局中布

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

(我的网格看起来像这样-第一列中的属性“name”,第二列中的属性“value”)


(网格的数据提供程序如下所示)

var retVal:ArrayCollection=新的ArrayCollection([
{属性:'AA',值:1},
{属性:'BB',值:},
{属性:'CC',值:“简单字符串”}
]);
仅属性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


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

你能帮我找出我所做的有什么问题吗?感谢您的帮助


“注意”

项渲染器是循环使用的,这意味着您应该期望任何一个渲染器实例都可以从列表中随机分配一个数据项(例如,数据设置器应该驱动任何可视更改)。不要忘记重置以前在不同数据项上渲染的状态

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


简短回答:创建一个itemRenderer。要让不同的行以不同的方式显示,将不会有更简单的方法。您必须根据数据更改格式或布局。如果您切换到Spark DataGrid,ItemRenderer函数可能会有所帮助。您好,Reboog711,我试图根据您之前的评论创建一个简单的示例,但无法实现。你能看一下并告诉我我做错了什么吗?我的第一列是一个属性(字符串),第二列是一个值,它可以是一个简单的字符串/数字,也可以是一个需要格式化的值数组。我正在为行保存数据对象,并使用它来渲染视图。我很确定我把钩子弄错了(特别是creationComplete的东西),但是Flex似乎没有一个简单的钩子可以让我覆盖。仅供参考:我刚刚修复了一个打字错误。。。引用this.data而不是传入的参数(在本例中,它不会造成不同,理论上是不正确的)只是好奇-addElement和addChild之间有什么区别?addChild级别较低,不推荐用于实现IVisualElementContainer的spark组件(您可以在自定义组件中添加一个图形或chrome元素,但可以添加元素将子元素附加到容器)。
<?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>
<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>
<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>