【问题标题】:DataGrid ItemRenderer ErrorDataGrid ItemRenderer 错误
【发布时间】:2011-11-03 16:06:16
【问题描述】:

我正在使用一个简单的 XML 文件填充我的数据网格的 3 列。最后一列应该是一个 itemrenderer,基本上是一个 Button。但是,该按钮应仅出现在数据网格的第 3 列的某些行上,具体取决于 XML 文件中的值,即“真”或“假”。所以基本上我想将 itemrenderer 中按钮的 Visible 属性设置为 true 或 false。

    Here is the whole application

    <?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" pageTitle="Dynamic Data Grid">
        <!--    <s:layout>
        <s:VerticalLayout horizontalAlign="center"/>
        </s:layout>-->

        <fx:Declarations>
            <s:ArrayList id="cccb_dp">
                <fx:String>User1</fx:String>
                <fx:String>User2</fx:String>
                <fx:String>User3</fx:String>
            </s:ArrayList>

            <fx:XML id="tempXML" source="assets/fieldsXML.xml"/>
            <s:XMLListCollection id="fieldsXMLList" source="{tempXML.worker}"/>

        </fx:Declarations>

        <s:layout>
            <s:VerticalLayout/>
        </s:layout>

        <s:VGroup verticalAlign="middle" horizontalCenter="1" verticalCenter="1" horizontalAlign="center">

            <s:HGroup horizontalAlign="center" verticalCenter="-221" width="580" height="158" x="75">
                <s:Label text="CC" width="23" height="24" verticalAlign="middle" fontWeight="bold"/>
                <s:DropDownList id="cc_cb" dataProvider="{cccb_dp}" width="175"/>
            </s:HGroup>

            <mx:DataGrid id="myDG" dataProvider="{fieldsXMLList}">
                <mx:columns>
                    <mx:DataGridColumn headerText="Header1" dataField="@field_label"/>
                    <mx:DataGridColumn headerText="Header2" dataField="@field_value"/>
                    <mx:DataGridColumn headerText="Header3">
                        <mx:itemRenderer>
                            <fx:Component>
                                <s:Button click="onClick(event)" label="Click Me" dataChange="onDataChange(event)" >
                                    <fx:Script>
                                        <![CDATA[
                                            import mx.controls.Alert;

                                            private function onClick(evt:Event):void
                                            {
                                                Alert.show(data.@field_visibility);
                                            }
                                            private function onDataChange(evt:Event):void
                                            {
                                                visible=data.@field_visibility;
                                            }
                                        ]]>
                                    </fx:Script>
                                </s:Button>
                            </fx:Component>
                        </mx:itemRenderer>
                    </mx:DataGridColumn>
                </mx:columns>
            </mx:DataGrid>

        </s:VGroup>

    </s:Application>


    The XML:
    <worker_fields>
        <worker id="1" field_label="Seller" field_value="5" field_visibility="false"/>
        <worker id="1" field_label="Balance" field_value="100" field_visibility="true"/>
        <worker id="1" field_label="Cash Owned" field_value="300" field_visibility="true"/>

        <worker id="2" field_label="Seller" field_value="5" field_visibility="false"/>
        <worker id="2" field_label="Balance" field_value="130" field_visibility="true"/>
        <worker id="2" field_label="Cash Owned" field_value="132" field_visibility="false"/>
        <worker id="2" field_label="Credits" field_value="131" field_visibility="true"/>
    </worker_fields>    


Any idea how to go around it.  

Thanks you for the precious help.

【问题讨论】:

    标签: xml apache-flex datagrid flex4


    【解决方案1】:

    每个itemRenderer 获取一个数据对象;其中包含渲染器正在显示的元素。在您的渲染器中不会有一个名为 field_visibility 的属性,因为它不是默认属性并且您没有创建它。

    但是,它应该是传递给渲染器的数据对象的属性。

    数据属性应该指向一个工人:

    <worker id="1" field_label="Cash Owned" field_value="300" field_visibility="true"/>
    

    您应该能够通过对您的代码稍加修改来访问它:

            <mx:itemRenderer>
                <fx:Component>
                    <mx:Button click="onClick(event)" label="Click Me" visible="{data.@field_visibility}">
                        <fx:Script>
                        <![CDATA[
                            import mx.controls.Alert;
    
                            private function onClick(evt:Event):void
                            {
                                Alert.show(data.field_visibility);
                            }
                        ]]>
                        </fx:Script>
                    </mx:Button>
                </fx:Component>
            </mx:itemRenderer>
    

    为了最好的结果;您应该考虑收听数据更改事件并以这种方式更改可见性。众所周知,从长远来看,这比使用绑定引起的问题更少:

            <mx:itemRenderer>
                <fx:Component>
                    <mx:Button click="onClick(event)" label="Click Me" dataChange="onDataChange()" >
                        <fx:Script>
                        <![CDATA[
                            import mx.controls.Alert;
    
                            private function onClick(evt:Event):void
                            {
                                Alert.show(data.field_visibility);
                            }
                            private function onDataChange(evt:Event):void
                            {
                                visible=data.@field_visibility";
                            }
                        ]]>
                        </fx:Script>
                    </mx:Button>
                </fx:Component>
            </mx:itemRenderer>
    

    由于某种原因,原始海报最后一次代码编辑抹去了他的实际问题。 Flex 在将 XML 字符串值转换为布尔值时遇到问题。 data.@field_visibility 似乎正在返回一个 XMLList。作为一个永远为真的布尔值。那是问题一。可以通过这样的条件来解决:

    if(data.@field_visibility == "true"){
     this.button.visible = true;
    } else {
     this.button.visible = false;
    }
    

    第二个问题是,如果按钮是顶级组件,它似乎不会消失。所以,你需要把它放在一个容器里。我用了画布。

    这是修改后的应用程序:

    <?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" pageTitle="Dynamic Data Grid">
        <!--    <s:layout>
        <s:VerticalLayout horizontalAlign="center"/>
        </s:layout>-->
    
        <fx:Declarations>
            <s:ArrayList id="cccb_dp">
                <fx:String>User1</fx:String>
                <fx:String>User2</fx:String>
                <fx:String>User3</fx:String>
            </s:ArrayList>
    
            <fx:XML id="tempXML" source="assets/fieldsXML.xml"/>
            <s:XMLListCollection id="fieldsXMLList" source="{tempXML.worker}"/>
    
        </fx:Declarations>
    
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    
        <s:VGroup verticalAlign="middle" horizontalCenter="1" verticalCenter="1" horizontalAlign="center">
    
            <s:Button click="{myDG.invalidateList()}" label="Invalidate List" />
            <s:HGroup horizontalAlign="center" verticalCenter="-221" width="580" height="158" x="75">
                <s:Label text="CC" width="23" height="24" verticalAlign="middle" fontWeight="bold"/>
                <s:DropDownList id="cc_cb" dataProvider="{cccb_dp}" width="175"/>
            </s:HGroup>
    
            <mx:DataGrid id="myDG" dataProvider="{fieldsXMLList}">
                <mx:columns>
                    <mx:DataGridColumn headerText="Header1" dataField="@field_label"/>
                    <mx:DataGridColumn headerText="Header2" dataField="@field_value"/>
                    <mx:DataGridColumn headerText="Header3">
                        <mx:itemRenderer>
                            <fx:Component>
                                <mx:Canvas dataChange="container1_dataChangeHandler(event)" >
                                    <mx:Button label="Click Me" id="button"  />
                                    <fx:Script>
                                        <![CDATA[
                                            import mx.events.FlexEvent;
    
                                            protected function container1_dataChangeHandler(event:FlexEvent):void
                                            {
                                                if(data.@field_visibility == "true"){
                                                    this.button.visible = true;
                                                } else {
                                                    this.button.visible = false;
                                                }
                                            }
    
                                        ]]>
                                    </fx:Script>
                                </mx:Canvas>
                            </fx:Component>
                        </mx:itemRenderer>
                    </mx:DataGridColumn>
                </mx:columns>
            </mx:DataGrid>
    
        </s:VGroup>
    
    </s:Application>
    

    【讨论】:

    • 绑定将因 XMLList 而失败。如果您不使用“dataChange”方法,所有按钮都将可见。
    • using data.@field_visibility 消除了错误,但它仍然不起作用。我和你的第二个建议完全一样。无论 field_visibility 的值为“true”还是“false”,该按钮都显示在 column3 的每一行上。有什么想法吗?
    • @RIAStar 感谢您的澄清;我不太会处理 XML。
    • @FlexyBoz 为我们提供了一个完整的可运行示例,我可以将其复制并粘贴到 Flex 应用程序中,然后我可以尝试。
    • @ www.Flextras.com 我编辑了原始问题并发布了一个示例应用程序。如果你能看看,不胜感激。谢谢
    【解决方案2】:

    除了@www.Flextras.com 的回答。

    如果您想依赖列的dataField 属性并使您的渲染器数据不可知,您可以在渲染器中实现mx.controls.listClasses.IDropInListItemRenderer 接口。至于您从已经实现它的 MX Button 继承,代码如下:

    <mx:DataGrid dataProvider="{fieldsXMLList}" id="myDG">
        <mx:columns>
            <mx:DataGridColumn dataField="@field_label" headerText="Header1" />
            <mx:DataGridColumn dataField="@field_value" headerText="Header2" />
            <mx:DataGridColumn dataField="@field_visibility" headerText="Header3">
                <mx:itemRenderer>
                    <fx:Component>
                        <mx:Button click="onClick(event)" label="Click Me" visible="{data[listData.dataField]}">
                            <fx:Script>
                            <![CDATA[
                                import mx.controls.Alert;
    
                                private function onClick(evt:Event):void
                                {
                                    Alert.show(data[listData.dataField]);
                                }
                            ]]>
                            </fx:Script>
                        </mx:Button>
                    </fx:Component>
                </mx:itemRenderer>
            </mx:DataGridColumn>
        </mx:columns>
    </mx:DataGrid>
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 2010-11-18
    • 2012-01-21
    • 1970-01-01
    • 2012-08-21
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多