3.4.1 窗体
- 目标
- 标识主片段,来装扮窗体
- 给窗体添加数据源,来定义窗体显示什么数据
- 给窗体添加控件,来显示数据
- 修改窗体方法,来控制打开和关闭时它的行为
- 决定在哪里放代码
- 运行时修改获取的数据
- 介绍
本科提供综合功能,使用窗体来与最终用户交互.
讨论一下话题:
- 窗体架构
- 获取数据
- 在船体中放置代码
- 先进的控件
- 特殊窗体
- 场景
系统开发人员,要创建一个新窗体,它有多个数据源链接在一起,一个字段从另一个字段计算而来,字段没有链接到数据源,当窗体打开时,初始化字段.同时,它也要调查其他类型的窗体和窗体控件.
- 架构
一个窗体提供用户和数据库的交互.它关注下面的动作:
- 显示和接收数据
- 过滤数据
- 排序数据
- 修改数据
应用和业务逻辑没有融入窗体,而是在底层的表和类上编程.
在AOT中,一个窗体由五个组件构成:
- 方法
- 数据源
- 部分
- 设计
- 权限
本课详细介绍三个主要节点:方法,数据源和设计.
- 方法
系统生成方法,也就是系统方法,标准方法或对象方法,附加在窗体上,用于控制启动和关闭窗体.这些时间按顺序地被覆盖,以初始化窗体.默认地,系统方法不显示.要覆盖一个系统方法,在方法节点右键,选择覆盖方法,并选择要覆盖的方法.
另外,可以添加方法,并在窗体的任何位置调用.这是好的实践,在这里添加方法,而不是在窗体设计的对象深层写大量代码,这样能使本地代码更简洁.
变量定义在类声明中,可以在所有窗体方法中访问,用于持有窗体控件的状态.
下面是CustTable窗体的方法.窗体系统方法task,run,init和close已经被覆盖.所有其他方法已经被添加到Methods节点.
- 数据源
数据源定义窗体和数据库之间的接口.一个实体被添加为每个表.每个数据源的属性表明数据源间的关系.每个数据源也有系统方法,可以被覆盖,用以控制显示数据或操作事件.
数据源包含表中的所有字段.再次,所有字段有属性和系统方法可以被覆盖.这些方法控制下列功能:
- 字段指定导航(过滤,查找,跳转到主表)
- 验证字段
- 修改字段
- 设计
窗体定义的设计,是窗体和用户的接口,它控制布局和数据表现.设计由调用的控件组件构成.一些控件用于编辑和显示数据,另一些用于控制窗体的布局.
一个窗体的一般设计如下
Design |
||||
Tab |
||||
TabPage |
||||
Grid |
||||
Fields to be displayed on Grid | ||||
TabPage |
||||
Field Groups |
||||
Fields in Field Group |
设计上的所有控件有属性和方法,并且可以被覆盖
在设计节点下,和设计节点一样,这里也有一个设计列表节点.
- 在窗体中处理对象
在窗体中编程时,你能引用对象个体,例如,数据源或窗体的控件,使用kernel类,来构建他们,或重写对象自己的方法.
窗体中的所有方法都关联到一个对象.该对象能使用this,从与它关联的方法中访问.注意this引用时关联到所有你编程.
当从方法中引用的一个对象,没有关联对象,你需要使用对象处理.下面是对象和如何访问他们
Object |
Access from X++ |
FormRun |
Element |
FormDataSource |
<name of data source>_DS |
Active record in data source |
<name of data source> |
FormDataObject |
FormDataSource.Object(<fieldId>) |
FormDesign |
FormRun.design() |
Form…Control |
指派给控件的名字,当AutoDeclaration设为Yes时.或element.control(Control::<name of control>) |
Query |
<name of data source>_Q 或 FormDataSource.Query() |
QueryRun |
<name of data source>_QR 或 FormDataSource.QueryRun() |
4 数据源
数据源中的表,能被用户排序或过滤,这是AX的一个重要特性.
窗体可以包含任何数量的数据源,并且每个数据源能通过定义表之间的关系,链接到窗体上的其他数据源.关系或Dynalinks也能在窗体代码中添加.
一个窗体数据源产生一个查询,它能以系统中任何其他查询一样的方式被执行.
4.1 joins
要从一个窗体的两个表中显示记录,指定一个两个表之间的连接.
在第二个表或被连接的表的JoinSource属性上指定连接.在这里填入主数据源的名字.
你也可以指定join 或link类型.link类型在后面描述.
CustInvoiceJour窗体使用连接.CustInvoiceTrans数据源被连接到CustInvoiceJour数据源,并且InventDim数据源被连接到CustInvoiceTrans数据源.
InventDim连接到CustinvoiceTrans,使用InnerJoin,因为数据被显示在和CustInvoiceTrans记录同一个fgrid里.
4.2 引用数据源
引用数据源,是一个数据源,被链接到父数据源上.通过代理键关系-RecId关系.
要从数据源中添加代理键字段到窗体设计,引用数据源会自动被创建,
4.3 从X++修改
使用查询对象来修改窗体数据源中的查询。该查询对象能使用<name of data source>_Q 或 FormDataSource.Query()来获取。
要对查询做永久修改,这个典型的实现,在FormDataSource.Init()中调用super()后。
在窗体中过滤记录,需哟遵循以下步骤:
- 在类声明中,声明相关的QueryBuildRange或QueryFilter对象。
- 在FormDataSource.Init中,实例化range对象。
- 在FormDataSource.ExecuteQuery中,在调用super()之前,指派范围的实际值。
通过添加排序字段,或添加一个索引给查询的数据源,来执行数据排序。作为一个替代,在数据源的属性上,制定一个索引。
使用一些聚合字段绑定排序,会使得数据源显示表中的聚合信息,而不是交易信息。执行以下步骤,显示每个产品id的库存交易的合计数量。
- 在数据源上,使用addGroupByField来按item id 分组。
- 添加Sum(Qty),作为SelectionField
4.4 要覆盖的公共方法
4.4.1 FormDataSource.Init
该方法初始化数据源,并被FormRun.Init的super()方法调用。当窗体打开时,该方法只被调用一次。
该方法的主要任务是实例化查询,用于获取数据。
要修改或替换窗体自动创建的查询,在该方法的super()方法后添加操作。
4.4.2 FormDataSource.InitValue
该方法用于使用默认值初始化一个新的记录。该方法的super()调用底层表的initValue()方法。
如果你要修改系统范围的,在该表上放代码。
4.4.3 FormDataSource.Active
数据源中的新记录变成活动状态时,调用该事件。该方法典型地覆盖,来改变依赖当前记录的内容的属性,通常,该方法会:
修改数据源的权限
修改字段的权限
启用/禁用按钮
4.4.4 FormDataSource.LinkActive
每次主数据元中的活动记录变更时,被联接的数据源就调用该方法。当床底作为系统层打开,联接到被调用窗体的主数据源,该方法也会被调用。
4.4.5 FormDataSource.ValidateWrite
该方法验证一个记录的插入或更新。该方法的super()调用底层表上相应的方法。
如果你要辨别插入和删除,在RecId字段上做一个条件,如果它是update,它只有一个值。
4.4.6 FormDataSource.Write
该方法控制记录的插入和删除。该方法的super()调用底层表上相应的方法。
如果你有窗体特殊任务要执行,在这里添加。