FormItems未在DataGroup中作为ItemRenderers对齐

时间:2013-07-30 08:46:30

标签: forms flex layout itemrenderer flex-spark

我正在尝试将FormItem用作DataGroup中的ItemRenderer - 目的是基于XMLlist作为数据提供者动态创建Form。第一部分是成功呈现表单项,但我的问题是尽管在DataGroup中使用了FormLayout,但我的FormItem标签并没有与彼此对齐。

<?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"
>
<fx:Declarations>
    <fx:XMLList id="_formModel" >
            <control description="Weeks 1 Form Item"  id="087B4626-B95E-731F-ACC7-80ED7373E083" label="One" />
            <control description="Weeks 2 Form Item"  id="AC546361-D9C5-E9F3-5F90-80EFA52EF54D" label="Second"  />
            <control description="Weeks 3 Form Item"  id="9EE2AAA4-B9C3-68C0-D9B5-80F0374F940E" label="Three" />
            <control description="Weeks 4 Form Item"  id="3CCEABD6-12F9-E511-0C77-80F0A86902D5" label="The Fourth"  />      
    </fx:XMLList> 
    <s:XMLListCollection id="_controls" source="{_formModel}"/>
</fx:Declarations>

<s:Scroller width="100%" height="100%">
    <s:DataGroup width="100%" height="100%" dataProvider="{_controls}"  >
        <s:layout>
            <s:FormLayout/>
        </s:layout>
        <s:itemRenderer>
            <fx:Component>
                <s:ItemRenderer>
                    <s:FormItem label="{data.@label}" width="100%"  >
                        <s:TextInput  width="100%"  text="{data.@description}"/>
                    </s:FormItem>
                </s:ItemRenderer>
            </fx:Component>
        </s:itemRenderer>  
    </s:DataGroup>
</s:Scroller>
</s:Application>

任何人都可以告诉我如何在数据组中使用它们时如何对齐表单项标签,因为练习的目的是动态地根据提供给数据组的数据创建表单。

提前致谢。

1 个答案:

答案 0 :(得分:4)

有趣的问题:我有一些乐趣解决它,结果比我预想的更容易。

问题

问题是FormItem必须是具有FormLayout的容器的直接子项,但在这种情况下,FormItemItemRenderer的子项,其中turn是DataGroup的孩子。

解决方案

要解决此问题,您可以创建FormItem的子类,该子类也实现IItemRenderer接口。这样DataGroup将知道如何处理这些项目,而FormItem将是FormLayout的直接子项。

代码

首先创建自定义项呈示器:

public class FormItemRenderer extends FormItem implements IItemRenderer {

    private var _data:Object;
    [Bindable("dataChange")]
    public function get data():Object { return _data; }
    public function set data(value:Object):void {
        _data = value;
        label = value ? value.@label : null;

        if (hasEventListener(FlexEvent.DATA_CHANGE))
            dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
    }

    private var _itemIndex:int;
    public function get itemIndex():int { return _itemIndex; }
    public function set itemIndex(value:int):void {
        if (value == _itemIndex) return;

        _itemIndex = value;
        invalidateDisplayList();
    }

    private var _selected:Boolean = false;
    public function get selected():Boolean { return _selected; }
    public function set selected(value:Boolean):void {
        if (value != _selected) {
            _selected = value;
            invalidateDisplayList();
        }
    }

    public function get dragging():Boolean { return false; }
    public function set dragging(value:Boolean):void { }

    public function get showsCaret():Boolean { return false; }
    public function set showsCaret(value:Boolean):void { }

}

我只实现了最低限度的工作;你可以在以后添加你需要的东西 另请注意data setter的第二行,我们将XML节点的label属性传递给FormItem的{​​{1}}属性。这不是一个非常通用的方法,但我想你可以在以后找到解决方案,如果需要的话。

现在使用自定义渲染器:

label

备注

您可以将此解决方案与<s:DataGroup dataProvider="{_controls}"> <s:layout> <s:FormLayout/> </s:layout> <s:itemRenderer> <fx:Component> <r:FormItemRenderer> <s:TextInput width="100%" text="{data.@description}"/> </r:FormItemRenderer> </fx:Component> </s:itemRenderer> </s:DataGroup> 开箱即用,但如果您想将其与DataGroup(或任何其他扩展List的组件)一起使用,还有一件事考虑:
ListBase不支持布局虚拟化,默认情况下会为列表启用布局虚拟化(无论如何对正常用例都没有意义)。因此,您必须明确将FormLayout设置为useVirtualLayout以避免NullPointerExceptions。

false