DataGrid ItemRenderer 错误

发布于 2024-12-01 03:52:09 字数 4200 浏览 1 评论 0原文

我使用一个简单的 XML 文件填充数据网格的 3 列。最后一列应该是一个 itemrenderer,基本上是一个 Button。但是,该按钮应该仅出现在数据网格第三列的某些行上,具体取决于 XML 文件中的值(“true”或“false”)。所以基本上我想将 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.

I am populating 3 columns of my datagrid using a simple XML file. The last column is supposed to be an itemrenderer, basically a Button. However the button should appear only on certain rows of the 3rd column of the datagrid depending on the value from the XML file, which is either "true" or "false". So basically I want to set the Visible property of the button in the itemrenderer to true or 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独夜无伴 2024-12-08 03:52:09

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

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

data 属性应该指向单个工作人员:

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

Each itemRenderer gets a data object; which contains the element the renderer is displaying. There is not going to be a property named field_visibility in your renderer because it is not a default property and you didn't create one.

However, it should be a property on the data object passed into the renderer.

The data property should point to a single worker:

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

And you should be able to access it with slight mods to your code:

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

For best results; you should consider listening to the data change event and changing the visibility in that way. This is known to cause less issues, long term, than the use of binding:

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

For some reason the original posters last code edit wiped out his actual question. Flex is having an issue translating the the XML string value into a Boolean value. data.@field_visibility appears to be returning an XMLList. As a Boolean value that will always be true. That is issue one. It can be solved by doing a conditional like this:

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

The second issue is that the button doesn't appear to vanish if it is the top level component. So, you need to place it inside a container. I used a Canvas.

Here is modified 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: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>
大海や 2024-12-08 03:52:09

除了@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>

In addition to @www.Flextras.com's answer.

If you want to rely on your column's dataField property and make your renderer data agnostic, you can implement mx.controls.listClasses.IDropInListItemRenderer interface in your renderer. As far as you inherited from MX Button which already implemented it the code will be the following:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文