首页 > 代码库 > 3.4.1 窗体

3.4.1 窗体

  1. 目标
  • 标识主片段,来装扮窗体
  • 给窗体添加数据源,来定义窗体显示什么数据
  • 给窗体添加控件,来显示数据
  • 修改窗体方法,来控制打开和关闭时它的行为
  • 决定在哪里放代码
  • 运行时修改获取的数据
  1. 介绍

本科提供综合功能,使用窗体来与最终用户交互.

讨论一下话题:

  • 窗体架构
  • 获取数据
  • 在船体中放置代码
  • 先进的控件
  • 特殊窗体
  1. 场景

系统开发人员,要创建一个新窗体,它有多个数据源链接在一起,一个字段从另一个字段计算而来,字段没有链接到数据源,当窗体打开时,初始化字段.同时,它也要调查其他类型的窗体和窗体控件.

  1. 架构

一个窗体提供用户和数据库的交互.它关注下面的动作:

  • 显示和接收数据
  • 过滤数据
  • 排序数据
  • 修改数据

应用和业务逻辑没有融入窗体,而是在底层的表和类上编程.

在AOT中,一个窗体由五个组件构成:

  • 方法
  • 数据源
  • 部分
  • 设计
  • 权限

本课详细介绍三个主要节点:方法,数据源和设计.

  1. 方法

系统生成方法,也就是系统方法,标准方法或对象方法,附加在窗体上,用于控制启动和关闭窗体.这些时间按顺序地被覆盖,以初始化窗体.默认地,系统方法不显示.要覆盖一个系统方法,在方法节点右键,选择覆盖方法,并选择要覆盖的方法.

另外,可以添加方法,并在窗体的任何位置调用.这是好的实践,在这里添加方法,而不是在窗体设计的对象深层写大量代码,这样能使本地代码更简洁.

变量定义在类声明中,可以在所有窗体方法中访问,用于持有窗体控件的状态.

下面是CustTable窗体的方法.窗体系统方法task,run,init和close已经被覆盖.所有其他方法已经被添加到Methods节点.

  1. 数据源

数据源定义窗体和数据库之间的接口.一个实体被添加为每个表.每个数据源的属性表明数据源间的关系.每个数据源也有系统方法,可以被覆盖,用以控制显示数据或操作事件.

数据源包含表中的所有字段.再次,所有字段有属性和系统方法可以被覆盖.这些方法控制下列功能:

  • 字段指定导航(过滤,查找,跳转到主表)
  • 验证字段
  • 修改字段
  1. 设计

窗体定义的设计,是窗体和用户的接口,它控制布局和数据表现.设计由调用的控件组件构成.一些控件用于编辑和显示数据,另一些用于控制窗体的布局.

一个窗体的一般设计如下

Design

       
 

Tab

     
   

TabPage

   
     

Grid

 
       

Fields to be displayed on Grid

   

TabPage

   
     

Field Groups

 
       

Fields in Field Group

设计上的所有控件有属性和方法,并且可以被覆盖

在设计节点下,和设计节点一样,这里也有一个设计列表节点.

  1. 在窗体中处理对象

在窗体中编程时,你能引用对象个体,例如,数据源或窗体的控件,使用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()后。

在窗体中过滤记录,需哟遵循以下步骤:

  1. 在类声明中,声明相关的QueryBuildRange或QueryFilter对象。
  2. 在FormDataSource.Init中,实例化range对象。
  3. 在FormDataSource.ExecuteQuery中,在调用super()之前,指派范围的实际值。

通过添加排序字段,或添加一个索引给查询的数据源,来执行数据排序。作为一个替代,在数据源的属性上,制定一个索引。

使用一些聚合字段绑定排序,会使得数据源显示表中的聚合信息,而不是交易信息。执行以下步骤,显示每个产品id的库存交易的合计数量。

  1. 在数据源上,使用addGroupByField来按item id 分组。
  2. 添加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()调用底层表上相应的方法。

如果你有窗体特殊任务要执行,在这里添加。