Saturday, 19 January 2019

Extensions through 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);
        }
        
    }

Source - 
https://community.dynamics.com/365/financeandoperations/b/365operationswithsukrut/archive/2018/01/15/customizing-d365-with-event-handlers