8.嵌入Freeform

8.1 普通嵌入

Supcan Treelist允许嵌入一个Freeform XML，来代替行的显示，相当于每行都是一个Freeform.
嵌入了Freeform后，数据行的外观就不再被限制在类似"表格"的范围了，数据展现可以相当地自由，演示页请参见“自由表头”中的“10.多记录Freeform(1)”、“12.多记录Freeform(2)”.
嵌入Freeform有一个最基本的要求：Treelist中的<col name="?">需要和Freeform中的<text/input/img id="?">相匹配.
满足了这一点后，Treelist就可以通过定义<Properties freeform="?" rowHeight="?" >引用该Freeform了.
嵌入的Freeform将代替Treelist各行的显示，也能代替Treelist的输入，是否能输入取决于Treelist的<Properties>中的 "Editable" 属性，且和Freeform中的<Properties> 的"Editable" 无关.
如果Treelist嵌入了Freeform，如下属性的默认值将和平常的不一样：
1.<Properties> \ headerHeight: 默认值将不是24，而是0，也就是说默认将没有表头;
2.<Properties> \ isShowRuler: 默认值将是true，也就是说默认显示左侧标尺;
3.<col> \ width: 默认值将不是0.1，而是0;

嵌入 Freeform 的 Treelist 不支持以树展现、不支持合计/小计行.

被嵌入的 Freeform 不支持 Menus、Upload、Pager、ImageFlow 类型的 Object.

8.2 Freeform对话框

有一种常见的应用场景是，数据平常以Treelist列表展现，如果要修改数据，只要按回车键(或鼠标双击)，就能弹出一个对话框，在对话框中输入数据。
您可以在“自由表头”中的 “15.辅助Treelist输入(2)” 演示页中实际操作一下，您会发现这种内置Freeform的非模式对话框输入方式，也是一种很不错的输入方案，尤其是在列多的情况下，输入一条记录变得直观简单，不必再来回拖拽底部的滚动条了。
<Properties>有一个属性 "editFreeformId"，就是用来指定这个输入的freeform对话框的，就如下面例子中的：

    <Properties editFreeformId="FR1"/>
    <cols>
     <col ...>
     ...
    </cols>
    <FreeformRes>
     <freeform id="FR1" url="freeform71.xml" IdOk="ok" IdCancel="cancel" extWidth="0"/>
     <freeform id="FR2" url="freeform72.xml" IdOk="ok" IdCancel="cancel" extWidth="0"/>
    </FreeformRes>
    ...

这种对话框有2种形式的freeform:
1.固定、写死的freeform;
2.动态生成、模版型的freeform
固定、写死的freeform就是普通的freeform，里面的所有元素都需要您亲手定义，在此就不再介绍。
动态freeform，是参照一个freeform模版生成的，该freeform中包含了<repeat>元素和<copy>元素，其含义分别为“动态替换” 和 “从Treelist复制”，典型例子如:

    <?xml version="1.0" encoding="utf-8"?>
    <!--Supcan Freeform -->
    <freeform>
    <Properties bgColor="#ffffff">
     <Expresses>
      〈Copy/〉　　//注：Expresses(表达式)将从 Treelist 复制
     </Expresses>
     <Validations>
      〈Copy/〉　　//注：Validations(验证)将从 Treelist 复制
     </Validations>
    </Properties>
    <Fonts>
     <Font height="-13"/>
    </Fonts>

    <Objects>
     <TableLayout x="5" y="42" width="95%">
      <Col width=".1"/>
      <Col width="90"/>
      <Col width="6"/>
      <Col width="190"/>
      <Col width="30"/>
      <Col width="90"/>
      <Col width="6"/>
      <Col width="190"/>
      <Col width=".1"/>
      〈repeat〉　　//注：本段内容将动态生成，里面有2个input, 表示垂直是双排的
       <tr height="24">
        <td/>
        <td><input width="3" leftTextAlign="left"/></td>
        <td/>
        <td/>
        <td/>
        <td><input width="3" leftTextAlign="left"/></td>
       </tr>
       <tr height="6"/>
      〈/repeat〉
     </TableLayout>
     <groupEx x1="5" y1="5" width="99%" y2=".bottom+8" text=" 请输入 "/>
     <input id="ok"  Text="确认" x="36%"  y=".bottom+10" width="80" type="button" />
     <input id="cancel"  Text="取消" x=".right+10"  y=".top" width="80" type="button" />
    </Objects>

    <DropLists>
     〈Copy/〉　　//注：Droplists(下拉资源)将从 Treelist 复制
    </DropLists>
    </freeform>

里面核心的部分就是<TableLayout>中的那段<repeat> ... </repeat>，其中的<input>只能含有width、leftTextAlign属性，不能书写其它的属性.
实际动态生成过程，只是替换其中的<repeat>和<copy>元素. 模版的最大好处是：复用.