执行操作 InvokeFieldUpdateService在插件中执行表单服务。
[tr][td]C#
[td]
[tr][td=2,1]// DataChanged更新价格同时执行表单服务规则(表单服务规则由IDE配置)// DataChanged中调用值更新和执行实体服务规则要注意不要引起递归调用public override void DataChanged(DataChangedEventArgs e){switch (e.Field.Key.ToUpper()) { case "FMATERIALID": // 修改物料时,清空单价 this.View.Model.SetValue("FPrice", 0, e.Row); //配送单分录 DynamicObjectCollection entries = this.View.Model.DataObject["DistributeOfBillEntry"] as DynamicObjectCollection; int row = 0; foreach (DynamicObject entry in entries) {decimal price = GetPriceFromIOSPriceList(); //不含税更新单价 entry["Price"] = price; this.View.InvokeFieldUpdateService("FPrice", row); row++; } //更新界面 this.View.UpdateView("FDistributeEntry"); break; default: break; }}
InvokeFormOperation调用表单操作。该方法应用场景:通常是在单元测试时动态调用表单操作,例如:
[tr][td]C#
[td]
[tr][td=2,1]// public class BusinessFlowTestAction : AbstractTestAction{ public override void Do() { //1.单据生成this.View.InvokeFormOperation(BOS.Core.DynamicForm.FormOperationEnum.New); this.ViewService.SetItemValueByNumber("FSettleId", "PRE001", 0);//结算币别=人民币 this.ViewService.UpdateValue("FQty", 0, 10); this.View.InvokeFormOperation(BOS.Core.DynamicForm.FormOperationEnum.Save); }}
Refresh刷新界面 。该刷新为整体刷新,等同于LoadData。对于某字段修改或单据体修改刷新请参考UpdateView方法。例如:列表插件中引入表单数据后刷新界面。(列表插件需继承AbstractListPlugIn)
[tr][td]C#
[td]
[tr][td=2,1]/// /// 引入操作后刷新列表/// /// public override void AfterDoOperation(AfterDoOperationEventArgs e){ base.AfterDoOperation(e); switch(e.Operation.Operation.ToUpper()) { case "IMPORTDATA": if (e.OperationResult.IsSuccess) { this.View.Refresh(); } break; }}
ShowForm显示动态表单界面,关闭窗体时有回调函数处理 ShowForm有2个方法,一个有回调函数一个没有,功能类似,差别仅仅是否需要执行回调方法。回调方法通常用于返回数据并处理返回来的数据。该方法中最重要的是要理解参数DynamicFormOpenParameter:
[tr][td=18][td=163]Name
[td=379]Description
[tr][td=18][td=163]Caption
[td=379]取发布到主控台那边的信息作为标题; 比如:同一个实体发票,发布到主控台后,有可能扮演普通发票与增值税发票的角色;
[tr][td=18][td=163]FormId
[td=379]动态表单编码
[tr][td=18][td=163]FormMetaData
[td=379]业务对象元数据模型
[tr][td=18][td=163]LayoutId
[td=379]布局编码
[tr][td=18][td=163]ObjectTypeId
[td=379]业务对象id
[tr][td=18][td=163]PageId
[td=379]本页面PageID
[tr][td=18][td=163]ParentPageId
[td=379]父页面PageID
[tr][td=18][td=163]SyncCallBackAction
[td=379]关闭时同步调用关闭回调函数
[tr][td]C#
[td]
[tr][td=2,1]// 点击分录行序列号单元格,打开序列号界面,查看序列号信息public override void EntryButtonCellClick(EntryButtonCellClickEventArgs e){ switch (e.FieldKey.ToUpper()) { case "FSERIALNO": ViewSerialMaster(e.Row); break; default: base.EntryButtonCellClick(e); break; }}
/// /// 链接查询序列号/// private void ViewSerialMaster(int index){ BillShowParameter billParam = new BillShowParameter(); billParam.FormId = K3.Core.SCM.SCMFormIdConst.BD_SerialMainFile; billParam.SyncCallBackAction = true; billParam.ParentPageId = this.View.PageId; billParam.PageId = Kingdee.BOS.Util.SequentialGuid.NewGuid().ToString(); billParam.Status = stats; billParam.PKey = snId.ToString(); this.View.ShowForm(billParam);}
示例显示:列表插件中点击新增后显示序列号编辑窗体,新增完成后刷新列表。
[tr][td]C#
[td]
[tr][td=2,1]public class StockSerialMainFileList : AbstractListPlugIn{ public override void AfterBarItemClick(AfterBarItemClickEventArgs e) { switch(e.BarItemKey.ToUpperInvariant()) { case "TBNEW" : case "TBSPLITNEW": case "TBNEWHAND": DynamicFormShowParameter listParam = new DynamicFormShowParameter(); listParam.Height = 600; listParam.Width = 800; listParam.FormId = "STK_SerialProduct"; listParam.SyncCallBackAction = true; listParam.ParentPageId = this.View.PageId; listParam.OpenStyle.ShowType = ShowType.Modal; listParam.PageId = Kingdee.BOS.Util.SequentialGuid.NewGuid().ToString(); listParam.CustomParams.Add("bType", "true"); this.View.ShowForm(listParam, new Action((result)=> { if (Convert.ToBoolean(result.ReturnData)) { this.View.Refresh(); } }) ); break; } }}
另外,BOS平台还提供两种显示特殊窗体方法:针对消息提供ShowMessage显示消息对话框。用法如下:ShowMessage(string [i]msg[/i], MessageBoxOptions[i][u]options[/u][/i], Action [i][u]action[/u][/i],string [i][u]title[/u][/i], MessageBoxType[i][u]msgType[/u][/i])参数:[i]msg [/i][i]消息内容[/i][i]options [/i][i]对话框操作[/i]
[tr][td=33%]Member
[td=64%]Description
[tr][td=33%]AbortRetryIgnore
[td=64%]有终止、重试、忽略按钮的对话框
[tr][td=33%]OK
[td=64%]有确定按钮的消息框
[tr][td=33%]OKCancel
[td=64%]有取消按钮的消息框
[tr][td=33%]RetryCancel
[td=64%]有重试、取消按钮的对话框
[tr][td=33%]YesNo
[td=64%]有是、否按钮的对话框
[tr][td=33%]YesNoCancel
[td=64%]有是、否和取消按钮的对话框
[i]action [/i][i]回调函数,常用于异步操作时,返回后需要处理的逻辑。[/i][i]title [/i][i]消息框标题[/i][i]msgType [/i][i]消息框的类型[/i]
[tr][td]Member
[td=65%]Description
[tr][td]Advise
[td=65%]警告
[tr][td]AskOK
[td=65%]确定按钮风格询问,[Obsolete]由MessageBoxOptions来确定
[tr][td]AskYes
[td=65%]是否按钮风格询问,[Obsolete]由MessageBoxOptions来确定
[tr][td]Error
[td=65%]错误
[tr][td]Notice
[td=65%]提示
例如使用异步方式显示消息窗体,用户确认后执行操作。
[tr][td]C#
[td]
[tr][td=2,1]// 需要确认,如删除前的提示;显示对话框,并且等待用户确认后,执行后续的回调函数this.View.ShowMessage(bdoArgs.Operation.FormOperation.ConfirmInfo.ToString(), MessageBoxOptions.YesNo, new Action((result) =>{ if (result == MessageBoxResult.Yes) {// 用户确认继续 opResult = Operation(callbackwf, bdoArgs.Result); }}));operResultFlag = false; //显示交互界面是异步操作,到这里并未真正执行操作,故返回false
针对操作结果提供ShowOperateResult显示批量操作结果。用法如下:void ShowOperateResult(OperateResultCollection[i]operateResults[/i], Action [i][u]action[/u][/i], string [i][u]formId[/u][/i])[i]参数:[/i][i]operateResults [/i]批量信息集合 [i]action [/i]回调函数 [i]formId [/i]可选,批量信息窗体的子类的标识如:在点击确定按钮时执行复核操作,异步显示操作结果,操作结果关闭时同时关闭当前界面。
[tr][td]C#
[td]
[tr][td=2,1]public override void ButtonClick(ButtonClickEventArgs e){ switch (e.Key.ToUpperInvariant()) { case "FOK": object selectedValue = this.View.Model.GetValue("FOperateType");//获取复核类型 int operateType = Convert.ToInt32(selectedValue); IOperationResult operationResult = CashierRecheckServiceHelper.Recheck(this.Context, lstVoucherIds, operateType); if(operationResult.OperateResult.Count==1) { this.View.ShowWarnningMessage(message); } else { this.View.ShowOperateResult(operationResult.OperateResult, r => this.View.Close()); } break; default: break; } base.ButtonClick(e);}
UpdateView刷新指定控件的数据及状态 3个方法分别用于:更新单据体某个单元格,参数:列的key,行号更新某个控件,参数:字段的key更新整个窗体新增角色分录行并刷新分录数据。
[tr][td]C#
[td]
[tr][td=2,1]// if (this.View.OpenParameter.Status == OperationStatus.ADDNEW){ DynamicObjectCollection cols = this.View.Model.GetEntityDataObject( this.View.Model.BusinessInfo.GetEntity("FEntityRole")); if (cols.IsEmpty()) { this.View.Model.CreateNewEntryRow("FEntityRole"); this.View.UpdateView("FEntityRole"); }}
设置默认组织并刷新默认组织显示。
[tr][td]C#
[td]
[tr][td=2,1]//设置默认组织this.View.Model.SetValue("FOrgId", orgId);_orgId = Convert.ToInt64(orgId);this.View.UpdateView("FOrgId");
新建嵌入子表单数据并刷新(嵌入表单)。
[tr][td]C#
[td]
[tr][td=2,1]var childView = this.View.GetView(this.childPageId) as IBillView;childView.CreateNewModelData();childView.UpdateView();
设置分录当前行弹性域字段,并触发实体服务,刷新当前行弹性域字段。
[tr][td]C#
[td]
[tr][td=2,1]flexField.DynamicProperty.SetValue(dynobj, cloneFlexObj);object flexIdValue = flexField.RefIDDynamicProperty.GetValue(copyObj);flexField.RefIDDynamicProperty.SetValue(dynobj, flexIdValue);this.View.InvokeFieldUpdateService(columnFKey, i);this.View.UpdateView(flexField.Key, i);
this.View.UpdateView()的使用时机1)UpdatView()是为了进行整单数据刷新,性能低,常用于批量数据操作(后面详细说)2)UpdateView(ctrl)是对给定key的控件进行刷新。3)UpdateView(ctrl, row)是对给定列表的给定行进行刷新。这里要说的是,通常情况下,当我们通过this.Model.SetValue方法进行赋值的时候,框架会自动进行数据的刷新。不需要我们再调用UpdateView。但是对于插件中为表体批量插入数据中提到的这种更新方法,因为BeginInitialize和EndInitialize之间会把Model针对View的回发机制关闭,因此控件数据就不会自动绑定了。在这种情况下,就应该在EndInitialize之后加上一句UpdateView来手工绑定。插件中为表体批量插入数据,推荐一种高效的批量插入数据方法:
[tr][td]C#
[td]
[tr][td=2,1] this.Model.BeginIniti(); foreach (DataRow row in dt.Rows) { int newEntry = this.Model.GetEntryRowCount("FResultList"); this.Model.CreateNewEntryRow("FResultList"); string msg = ""; if (type == "I") { if (System.Convert.ToInt32(row["FStatus"]) == -1) //已存在 { msg = "【{0}】已存在于【{1}】中"; } else { msg = "【{0}】成功下发到【{1}】"; } } else if (type == "C") { if (System.Convert.ToInt32(row["FStatus"]) == 1) //已存在 { msg = "【{0}】成功从【{1}】中取消下发"; } else { msg = "【{0}】在【{1}】中不存在"; } }this.Model.SetValue("FNote", String.Format(msg, row["FName"], row["FOrg"]), newEntry); this.Model.SetValue("FBaseDataNumber", row["FNumber"], newEntry); this.Model.SetValue("FBaseDataName", row["FName"], newEntry); this.Model.SetValue("FDestOrgNumber", row["FOrgNumber"], newEntry); this.Model.SetValue("FDestOrgName", row["FOrg"], newEntry);}this.Model.EndIniti();this.View.UpdateView("FResultList");