Skip to main content

Notifications

Customizing D365 with event handlers

Sukrut Parab Profile Picture Sukrut Parab 71,656 Moderator

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 which are going to help you while doing common scenarios like how to get form datasource , form controls etc.. in 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

 

Comments

*This post is locked for comments

  • CAHE4KA Profile Picture CAHE4KA 10
    Posted at
    Ann2015, right-click the Event in the Form designer and select Find event handlers
  • Ann2015 Profile Picture Ann2015 1,120
    Posted at

    if there is already a custom code in the method, how can I see that ?

    I know I can copy and create a new event handlers but how do I know what's in the code already? Is there any way to view it? Thank u . Ann