我正在尝试将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>
任何人都可以告诉我如何在数据组中使用它们时如何对齐表单项标签,因为练习的目的是动态地根据提供给数据组的数据创建表单。
提前致谢。
答案 0 :(得分:4)
有趣的问题:我有一些乐趣解决它,结果比我预想的更容易。
问题是FormItem
必须是具有FormLayout
的容器的直接子项,但在这种情况下,FormItem
是ItemRenderer
的子项,其中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