四.业务单据窗体开发步骤-业务单据窗体-C/S快速开发框架-标准版V2.3
目录
- 4.1 新建业务窗体
- 4.2窗体布局设计
- 4.3 使用代码生成器工具生成ORM、BLL、DAL代码
- 4.4 BLL层代码
- 4.5 DAL层代码
- 4.6 编写窗体代码
- 4.6.1 初始化业务窗体(重写InitializeForm方法)
- 4.6.2 Form.Load事件调用InitializeForm方法
- 4.6.3 实现查询功能(DoSearchSummary方法)
- 4.6.4 绑定主表输入组件数据源(DoBindingSummaryEditor方法)
- 4.6.5 绑定明细表格的数据源(DoBindingDetailGrid方法)
- 4.6.6 增加(DoAdd方法)
- 4.6.7 删除(DoDelete方法)
- 4.6.8 修改(DoEdit方法)
- 4.6.9 查看(DoViewContent方法)
- 4.6.10 取消(DoCancel方法)
- 4.6.11 打印(DoPrint方法)
- 4.6.12 审核(DoApproval方法)
- 4.6.13 保存(DoSave方法)
- 4.6.14主表数据合法性检查(ValidatingSummaryData方法)
- 4.6.15 明细表数据合法性检查(ValidatingDetailData方法)
- 4.6.16 显示修改历史记录(DoShowModifyHistory方法)
- 4.6.17 其它细节处理
4.1 新建业务窗体
4.1.1 在销售模块新建[frmSO]窗体
在【销售模块】点右键,【Add】【New Item】打开【新建项对话框】。
4.1.2 [新建项]对话框
在【Name】输入框输入【frmSO.cs】,最后点【Add】按钮弹出【Inheritance Picker窗体】。
4.1.3 [Inheritance Picker]对话框
选择继承自【frmBaseBusinessForm】,点【OK】按钮,新建窗体的单元文件。
4.2窗体布局设计
4.2.1 用户界面介绍
数据查询页:用于展示主表查询结果,表格只读,不可修改。
数据编辑页:编辑表格中当前选择的记录(单据), 显示详细资料,用户在数据编辑页修改数据。
4.2.2 数据查询页及主表格(GridControl)控件
4.2.2.1 设计查询面板
从工具箱拖放PanelControl l组件,Dock设为Top,在PanelControl内拖放一组查询条件输入框及查询按钮。
4.2.2.2 拖放主表表格
从工具箱拖放PanelControl l组件,Dock设为Client,在PanelControl内拖放一个GridControl组件,然后改名,如下图:
GridControl可以从其它窗体数据查询页复制过来,这样不需要设置参数,节省时间。
4.2.2.3 在GridView(gvSummary)内定义表格的栏位
表格的栏位设计页面
新增一个栏位
栏位的属性设置。主要修改(Name),Caption,FieldName三个属性。
属性名称 | 说明 |
(Name) | 栏位名称(列名)。建议用col+字段名命名,如:colCustomerCode |
Caption | 栏位的标题。如:客户编号 |
FieldName | 栏位对应的字段名,用于绑定数据。如字段名:CustomerCode |
关闭设计器,表格内定义了以下栏位:
4.2.3 数据编辑页面设计[主/从表输入区域]
通常业务单据只有一个明细表,设计效果如下:
有些业务单据比较复杂,比如多个明细表的,设计效果如下:
此委托加工单有3个明细表,其中两个明细表用TabPage收缩到一个区域。
4.2.4 主表输入组件设计
输入框建议以txt+字段名命名,如SONO 销售订单字段命名为txtSONO, CheckBox用缩写chk,如chkAPP审核。
4.3 使用代码生成器工具生成ORM、BLL、DAL代码
代码生成器可生成ORM实体及DAL,BLL层代码模板。单表如数据字典生成的代码几乎不需要修改即可运行,业务单据功能较复杂,除框架实现的功能外,需要用户扩展方法。SO功能扩展的方法有CheckNoExists,GetSummaryByParam,GetReportData。
开发框架仅能生成BLL,DAL代码模板,实际上用户需要跟据业务需求自行扩展代码。通过修改代码生成器的模板部分,用户可以生成适合当前项目的代码。
代码生成步骤:ORM->DAL->BLL。
4.3.1 生成ORM
4.3.2 生成DAL
4.3.3 生成BLL
生成后将代码加入解决方案,尝试编译。
4.3.1 参考视频:
4.4 BLL层代码
BLL,Business Logic Layer 业务逻辑层。关于C/S结构开发框架中BLL层请参考:
http://www.csframework.com/archive/1/arc-1-20110414-1332.htm
4.4.1 BLL继承关系图
如上图所示,bllBase是所有业务层的基类,bllBaseBusiness是业务单据的业务逻辑层基类,实现ILogSupportable接口,该接口用于处理修改日志功能。
所有业务单据的逻辑层从bllBaseBusiness派生,如bllPO,bllSO。
4.4.2 bllBaseBusiness类
bllBaseBusiness类是业务单据的业务逻辑层基类,实现了业务单据所需的公共方法,虚方法便于派生类重写功能。
bllBaseBusiness类说明:
ID | 名称 | 类型 | 说明 |
1 | AllowWriteLog | 标记允许写入修改日志。 | |
2 | ApprovalBusiness | 审核功能的方法。 | |
3 | BusinessTables | 对应当前业务单据的数据. DataTableCollection类型, 第1个表(Index为0)为主表,其它为明细表。 | |
4 | ClearAppInfo | 清空审核功能相关字段的数据。 | |
5 | CreateSaveData | 创建用于保存的临时数据。 | |
6 | CurrentBusiness | 当前业务单据的数据。 | |
7 | DataBinder | 对应当前单据的主表数据 (DataTable), 该表只有一条记录,用于绑定[数据修改页面]输入组件的数据源。 | |
8 | DataBindRow | DataRow类型,对应DataBinder的第一条记录。 | |
9 | Delete | 删除单据。 | |
10 | DoCreateTempData | 创建用于保存的临时数据。该方法由CreateSaveData方法调用。 | |
11 | GetAttachedFiles | 获取单据附件数据。 | |
12 | GetBusinessByKey | 下载指定单号的业务数据。 | |
13 | IsApproved | 检查业务单据是否审核。 | |
14 | IsOwnerChange | 比较当前登录用户与制单人是否一致。 | |
15 | KeyFieldName | 业务单据的主键字段名。 | |
16 | SummaryTableName | 业务单据的主表名称。 | |
17 | NewBusiness | 新增业务数据。 | |
18 | NotifyUser | 当单据被修改发送手机短信或Email给制单人。 | |
19 | Save | 保存业务数据。 | |
20 | SaveAttachedFile | 保存附件。 | |
21 | UpdateDetailCommonValue | 更新业务单据明细表的公共字段数据。 | |
22 | UpdateSummaryRowState | 更新记录状态。 | |
23 | WriteLog | 保存修改日志。 |
类成员截图:
4.4.3 bllSO类
SO,Sales Order销售订单,继承bllBaseBusiness基类。
bllSO类说明:
ID | 名称 | 类型 | 说明 |
1 | ApprovalBusiness | 重载的方法,用于审核单据。 | |
2 | CheckNoExists | 检查单据号码是否存在。 | |
3 | CreateSaveData | 重载的方法,创建用于保存的临时数据。 | |
4 | Delete | 重载的方法,删除单据。 | |
5 | FuzzySearch | 产品资料模糊查询。实现IfuzzySearchSupportable接口, 在 frmFuzzySearch窗体中使用。 | |
6 | FuzzySearchName | 模糊查询功能的名称,如:产品资料查询。在frmFuzzySearch窗体的标题显示。 | |
7 | GetReportData | 获取报表数据。 | |
8 | GetBusinessByKey | 重载的方法,下载指定单号的业务数据。 | |
9 | GetSummaryByParam | 查询销售订单的主表数据,查询结果在主表格中显示。 | |
10 | NewBusiness | 重载的方法,新增业务数据。 | |
11 | Save | 重载的方法,保存数据。 | |
12 | WriteLog | 重载的方法,保存修改日志。 |
类成员截图:
4.5 DAL层代码
DAL,Data Access Layer数据访问层。关于C/S开发框架中数据访问层(DAL)的作用请参考:
http://www.csframework.com/archive/1/arc-1-20110414-1333.htm
4.5.1 DAL继承关系图
上图所示,dalBase是数据访问层的基类,dalBaseBusiness是业务单据数据层的基类,业务单据的DAL从dalBaseBusiness类继承,如dalPO,dalSO。
4.5.2 dalBaseBusiness类
ID | 名称 | 类型 | 说明 |
1 | _SummaryKeyName | 主表主键字段名。 | |
2 | _SummaryTableName | 主表表名。 | |
3 | _UpdateSummaryKeyMode | 业务单据号码更新类型(自动生成流水号或GUID)。 | |
4 | ApprovalBusiness | 单据审核/批准功能。。 | |
5 | CheckNoExists | 检查业务数据是否存在。 | |
6 | CreateSqlGenerator | 虚方法,根据表名获取该表的ORM及对应的SQL命令生成器。 | |
7 | GetNumber | 获取单据流水号码。 | |
8 | Update | 保存数据,对应BLL.Save方法 | |
9 | UpdateDetailKey | 更新明细表的外键。 | |
10 | UpdateSummaryKey | 更新主表主键。 |
类成员截图:
4.5.3 dalSO类
类成员列表
ID | 名称 | 类型 | 说明 |
1 | CreateSqlGenerator | 重载的方法,根据表名获取该表的ORM及对应的SQL命令生成器。 | |
2 | Delete | 删除单据,开发框架的模板窗体仅删除明细表,将主表数字类型的字段清零,如金额,数量等关键字段,保留主表的记录避免断号。 | |
3 | GetBusinessByKey | 获取一张业务单据的数据。 | |
4 | GetNumber | 获取单据流水号码, 首先在sys_DocSN表设置单据的超始号。 | |
5 | GetReportData | 根据查询条件获取报表数据。 | |
6 | GetSummaryByParam | 查询销售订单的主表数据。 |
类成员截图:
4.6 编写窗体代码
设计好窗体上的组件及界面布局,然后使用工具生成ORM,BLL,DAL层的代码,最后手工编写窗体内的代码。开发框架的数据窗体模板就两种,为了快速开发我们可以直接引用frmSO,frmPO窗体的代码。
窗体与业务逻辑层的引用关系:
开发框架将用户界面与业务逻辑代码分离出来的,所以任何与业务有关的操作建议封装到业务层,大大减少用户界面的代码量,使界面与业务代码松散藕合,用户界面仅保留操作本窗体组件的代码及引用业务层的代码。
4.6.1 初始化业务窗体(重写InitializeForm方法)
InitializeForm()是frmBaseDataForm窗体中定义的虚方法,派生的窗体必须在Form.Load事件中调用。
InitializeForm方法主要功能是:
1. 实例化业务层_BLL变量。
2.调用公共方法设置表格样式。
3. 绑定主表表格及明细表表格的事件。
4.绑定数据参照组件(LookupEdit)的数据源。
5. 加载一个空的业务对象,用于测试网络环境及初始化数据。
请参考frmSO. InitializeForm方法
4.6.2 Form.Load事件调用InitializeForm方法
private void frmSO_Load(object sender, EventArgs e)
{
this.InitializeForm(); //初始化主窗体
}
4.6.3 实现查询功能(DoSearchSummary方法)
首先实现查询功能显示主表的数据,非常简单,在窗体内重载DoSearchSummary方法,然后调用BLL层的GetSummaryByParam方法,该方法的参数跟据查询条件定义,通常查询单据号码,日期范围及客户编号。
流程如下:
请参考frmSO. DoSearchSummary方法
4.6.4 绑定主表输入组件数据源(DoBindingSummaryEditor方法)
实现DoSearchSummary方法后可查询数据,现在我们需要展示业务单据的详细资料。销售订单只有一个从表,用一个表格展示明细数据。主表的资料用输入框展示。重写DoBindingSummaryEditor方法绑定输入框的数据源。
请参考frmSO. DoBindingSummaryEditor方法
4.6.5 绑定明细表格的数据源(DoBindingDetailGrid方法)
重写DoBindingDetailGrid方法绑定销售订单明细表的数据源。DoBindingDetailGrid
是frmBaseBusinessForm窗体中定义的虚方法。
请参考frmSO. DoBindingDetailGrid方法
4.6.6 增加(DoAdd方法)
销售订单不需要直接实现DoAdd方法,在frmBaseBusinessForm窗体中该方法调用业务层的虚方法,所以我们只需要实现派生类bllSO中相关方法就行。
销售订单的新增功能处理流程:
- 调用业务层的GetBusinessByKey方法,下载一个空的业务单据DataSet。
- 调用业务层的NewBusiness方法,新增一条记录并初始化数据,如单据日期,制单人等预设值。
- 绑定主表,明细表的数据源。
- 将状态改为UpdateType.Add。
- 显示详细资料页面。
请参考frmBaseBusinessForm. DoBindingDetailGrid方法
及bllSO. GetBusinessByKey, NewBusiness
4.6.7 删除(DoDelete方法)
销售订单不需要直接实现DoDelete方法,在frmBaseBusinessForm窗体中该方法调用业务层的虚方法,所以我们只需要实现派生类bllSO中相关方法就行。
销售订单删除功能处理流程:
1. 调用BLL的IsApproved方法检查单据是否已经审核,已审核的单据禁止删除。
2. 调用BLL的Delete方法删除销售订单的明细表及将主表的金额等字段的数据置零。
3. 如后台数据删除成功,将主表格当前记录的金额等字段的数据置零。
请参考frmBaseBusinessForm. DoDelete方法
及bllSO. IsApproved, Delete
4.6.8 修改(DoEdit方法)
销售订单不需要直接实现DoEdit方法,在frmBaseBusinessForm窗体中该方法调用业务层的虚方法,所以我们只需要实现派生类bllSO中相关方法就行。
销售订单的修改功能处理流程:
1. 调用BLL的IsOwnerChange方法检查单据的制单人是否为当前用户,不能修改他人创建的单据。
2. 调用BLL的IsApproved方法检查单据是否已经审核,已审核的单据禁止删除。
3. 调用DoViewContent方法显示当前单据的详细资料。
4. 将状态改为UpdateType.Modify。
5. 显示详细资料页面。
请参考frmBaseBusinessForm. DoEdit方法
及bllSO. IsApproved, IsOwnerChange
4.6.9 查看(DoViewContent方法)
销售订单不需要直接实现DoViewContent方法,在frmBaseBusinessForm窗体中该方法调用业务层的虚方法,所以我们只需要实现派生类bllSO中相关方法就行。
销售订单的查看功能处理流程:
1. 调用业务层的GetBusinessByKey方法下载业务单据数据集DataSet,参数:当前单据号码。
2. 绑定主表,明细表的数据源。
3. 将状态改为UpdateType.None。
4. 显示详细资料页面。
请参考frmBaseBusinessForm. DoViewContent方法
及bllSO. GetBusinessByKey
4.6.10 取消(DoCancel方法)
销售订单不需要直接实现DoCancel方法,在frmBaseBusinessForm窗体中已实现具体功能。
销售订单的取消功能处理流程:
1. 调用DoViewContent方法重新显示当前单据。
2. 将状态改为UpdateType.None。
请参考frmBaseBusinessForm. DoCancel方法
4.6.11 打印(DoPrint方法)
打开打印窗体。
请参考frmSO. DoPrint方法
4.6.12 审核(DoApproval方法)
销售订单不需要直接实现DoApproval方法,在frmBaseBusinessForm窗体中该方法调用业务层的虚方法,所以我们只需要实现派生类bllSO中相关方法就行。
销售订单的审核功能处理流程:
1. 调用BLL的IsApproved方法检查单据是否已经审核,已审核的单据不能重复审核。
2. 调用BLL的ApprovalBusiness方法审核单据。
请参考frmBaseBusinessForm. DoApproval方法及bllSO. ApprovalBusiness
4.6.13 保存(DoSave方法)
销售订单的保存功能处理流程:
1. 更新最后获得焦点输入框的数据及主表的汇总金额。
2. 主、从表的数据合法性检查。
3. 保存本次修改日志记录。
4. 创建用于保存的临时数据集。bllBaseBusiness类的_CurrentBusiness成员是当前正在处理的业务数据,通常在保存前会做些特殊处理,如设置单号,某些日期及单据的关联数据,为了不影响原始数据,我们在保存前复制一个副本用于保存,即使保存失败也不影响当前正在处理的业务数据。
5. 调用BLL.Save方法。
6. 如保存成功,前台相关处理。
7. 将状态改为UpdateType.None。
请参考frmSO. DoSave方法及bllSO. Save
4.6.14主表数据合法性检查(ValidatingSummaryData方法)
请参考frmSO. ValidatingSummaryData方法
4.6.15 明细表数据合法性检查(ValidatingDetailData方法)
请参考frmSO. ValidatingDetailData方法
4.6.16 显示修改历史记录(DoShowModifyHistory方法)
打开frmModifyLog窗体显示修改历史记录。
请参考frmSO. DoShowModifyHistory方法
4.6.17 其它细节处理
ID | 名称 | 类型 | 说明 |
1 | ButtonAuthorized | frmBaseChild窗体中定义的虚方法。派生类通过重写该方法可以检查按钮的权限并隐藏工具栏的按钮。 | |
2 | ButtonStateChanged | frmBaseDataForm窗体中定义的虚方法。当按钮状态发生变化时调用,可以重写此事件禁用某些输入组件。 | |
3 | CreateOneDetail | 创建一条明细记录,适用于有明细表的业务窗体。此方法由 OnEmbeddedNavigatorButtonClick事件调用。
明细表格的导航按钮新增了三个自定义按钮,如下图:
分别是新增,插入,删除。在InitializeForm方法中调用 DevStyle.SetGridControlLayout(gcDetail, true)方法创建3个按钮,但必须将第2个参数allowEdit为true。
CreateOneDetail方法的buttonIndex参数对应按钮的序号,分别为0:Add,1:Insert,2:Delete,在枚举类型DetailButtons中定义。
插入记录功能需要定义Queue字段,带符号的数字类型,用于排序。
| |
4 | OnCellValueChanged | 明细表格的OnCellValueChanged事件,当用户修改明细表单元格的数据时触发该事件。可以在此事件内计算总金额(金额=单价*数量) | |
5 | OnStockCode_ButtonClick | 明细表的货品栏位支持选择功能,将栏位设置为ButtonEdit类型。 运行效果图如下:
点ButtonEdit的按钮触发OnStockCode_ButtonClick事件。 在InitializeForm方法中绑定OnStockCode_ButtonClick事件。 | |
6 | OnStockCode_Validating | 用户可以选择或输入货品编码,当用户输入货品编码后离开当前单元格时触发OnStockCode_Validating事件。 在InitializeForm方法中绑定OnStockCode_Validating事件。 | |
7 | SearchStockCallBack | 跟据货品编号获取货品详细资料,该方法由 OnStockCode_ButtonClick和OnStockCode_Validating事件调用。 | |
8 | SetDetailEditorsAccessable | 在frmBaseDataForm窗体中定义的虚方法,用于控制明细页面上的控件可被编辑,同时禁用或启用明细表三个自定义按钮。 | |
9 | UpdateDetailAmount | 自动计算明细表的金额合计,在OnCellValueChanged事件中调用。 | |
10 | UpdateTotalAmount | 自动计算主表的总金额。 主表的总金额=SUM(明细表的金额)。 通常在保存前会重新计算主表的总金额。 |