Customizing D365 with event handlers
With Dynamics 365 release we have to do most of the things using extensions and event handlers. You still have an option to over layer code. While creating new package if you choose select existing packages and modified any standard object which belongs to that package, you are doing overlaying. In previous versions it was not a big issue but with new release we should stop doing that and instead embrace a practice of doing customizations using extensions and event handlers.
Source code and metadata of model elements can be extended without an over-layering using extensions.
Today I will share some code snippets about how to do few things while using event handlers
How to get Form Datasource
If you copy form event handler here is how you can get form datasource from XFormRun
If you copy form datasource event you can get form run object from datasource as below. Once you get form run you can call any form method available on the form.
Similarly you can get formrun on a from control event handler using FormControl
To get control on a form and make it editable or non-editable
Getting current record
Hcmposition is first datasource on HcmPosition form that’s why gave 1 in datasource.
Using DataEventArgs to send Validation result
Similarly you can use on ValidateFieldValueEventArgs to send validation result back to Validate Field method
More information about customizing using extensions can be found here
Source code and metadata of model elements can be extended without an over-layering using extensions.
Today I will share some code snippets about how to do few things while using event handlers
How to get Form Datasource
If you copy form event handler here is how you can get form datasource from XFormRun
[FormEventHandler(formStr(HcmPosition), FormEventType::Initialized)] public static void HcmPosition_OnInitialized(xFormRun sender, FormEventArgs e) { FormDataSource hcmosition_ds = sender.dataSource(formDataSourceStr(HcmPosition, HcmPosition)); Or FormDataSource hcmosition_ds = sender.dataSource('HcmPosition'); }
If you copy form datasource event you can get form run object from datasource as below. Once you get form run you can call any form method available on the form.
[FormDataSourceEventHandler(formDataSourceStr(HcmPosition, HcmPosition), FormDataSourceEventType::Created)] public static void HcmPosition_OnCreated(FormDataSource sender, FormDataSourceEventArgs e) { FormRun formRun = sender.formRun() as FormRun; }
Similarly you can get formrun on a from control event handler using FormControl
[FormControlEventHandler(formControlStr(HcmPosition, HcmPosition_PositionId1), FormControlEventType::Modified)] public static void HcmPosition_PositionId1_OnModified(FormControl sender, FormControlEventArgs e) { FormRun formRun = sender.formRun() as FormRun; }
To get control on a form and make it editable or non-editable
[FormEventHandler(formStr(HcmPosition), FormEventType::Initialized)] public static void HcmPosition_OnInitialized(xFormRun sender, FormEventArgs e) { sender.design().controlName(formControlStr(HcmPosition, HcmPositionNewPosition)).AllowEdit(false); // to get form open Mode OpenMode openMode = sender.args().openMode(); }
Getting current record
Hcmposition is first datasource on HcmPosition form that’s why gave 1 in datasource.
[FormControlEventHandler(formControlStr(HcmPosition, HcmPositionNewPosition), FormControlEventType::Clicked)] public static void HcmPositionNewPosition_OnClicked(FormControl sender, FormControlEventArgs e) { HcmPosition hcmposition = sender.formRun().dataSource(1).cursor(); }
Using DataEventArgs to send Validation result
[DataEventHandler(tableStr(CategoryTable), DataEventType::ValidatingDelete)] public static void CategoryTable_onValidatingDelete(Common _sender, DataEventArgs _e) { CategoryTable categoryTable = _sender as CategoryTable; ValidateEventArgs validateEventArgs = _e as ValidateEventArgs; boolean ret = true; if (categoryTable.UseInProject) { ProjCategory projCategory = ProjCategory::find(categoryTable.CategoryId); ret = projCategory.validateDelete(); } if (ret && categoryTable.UseInExpense) { TrvCostType trvCostType = TrvCostType::find(categoryTable.CategoryId); ret = trvCostType.validateDelete(); } if (!ret) { validateEventArgs.parmValidateResult(false); } }
Similarly you can use on ValidateFieldValueEventArgs to send validation result back to Validate Field method
[DataEventHandler(tableStr(LedgerParameters), DataEventType::ValidatingFieldValue)] public static void LedgerParameters_onValidatingFieldValue(Common sender, DataEventArgs e) { ValidateFieldValueEventArgs ve = e; boolean isValid = true; LedgerParameters ledgerParameters = sender as LedgerParameters; #isoCountryRegionCodes if (ve.parmFieldName() == fieldStr(LedgerParameters, ChineseVoucher_CN) && SysCountryRegionCode::isLegalEntityInCountryRegion([#isoCN])) { if ((select firstonly RecId from LedgerJournalTrans where LedgerJournalTrans.LedgerVoucherType_CN != 0 || LedgerJournalTrans.Voucher_CN != '').RecId != 0) { // The general journal needs to be empty in order to modify the setup for the Chinese voucher system. isValid = checkFailed("@GLS54497"); } ve.parmValidateResult(isValid); } }
More information about customizing using extensions can be found here
The Best of the Blogs You have Mentioned here.
ReplyDeleteMicrosoft Dynamics AX Online Training