Header Ads Widget

🔧 Mastering Event Handlers in D365FO with Practical Examples – Table, Form, and DataSource

🔍 Introduction

Event handlers in Dynamics 365 Finance and Operations (D365FO) provide developers the ability to execute custom logic without modifying base object methods. In this guide, we'll explore Table, Form, and DataSource-level event handlers, with real-time rewritten examples using unique buffer names to ensure fresh and non-repetitive code.


📁 Table Event Handlers

ValidatedField Event Handler

x++
[DataEventHandler(tableStr(MySalesTable), DataEventType::ValidatedField)] public static void MySalesTable_onValidatedField(Common _sender, DataEventArgs _e) { ValidateFieldEventArgs validateArgs = _e as ValidateFieldEventArgs; MySalesTable mySalesRec = _sender as MySalesTable; boolean isValid = validateArgs.parmValidateResult(); // Custom logic here }

✅ Post Handler for validateField

x++
[PostHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, validateField))] public static void MySalesTable_Post_validateField(XppPrePostArgs _args) { MySalesTable salesBuffer = _args.getThis(); FieldId fldId = _args.getArg("_fieldId"); boolean originalResult = _args.getReturnValue(); // Optional logic _args.setReturnValue(originalResult); }

🆕 initValue Pre and Post Handlers

Post:

x++
[PostHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, initValue))] public static void MySalesTable_Post_initValue(XppPrePostArgs _args) { MySalesTable postInitRec = _args.getThis(); }

Pre:

x++
[PreHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, initValue))] public static void MySalesTable_Pre_initValue(XppPrePostArgs _args) { MySalesTable preInitRec = _args.getThis(); }

✍️ Inserted Data Event Handler

x++
[DataEventHandler(tableStr(MySalesTable), DataEventType::Inserted)] public static void MySalesTable_onInserted(Common _sender, DataEventArgs _e) { ValidateEventArgs insertArgs = _e as ValidateEventArgs; MySalesTable insertedBuffer = _sender as MySalesTable; }

🔄 Post Handler for Custom Update Method

x++
[PostHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, updateSalesStatus))] public static void MySalesTable_Post_updateSalesStatus(XppPrePostArgs _args) { MySalesTable updatedRec = _args.getThis(); }

✏️ modifiedField Event Handlers

Pre:

x++
[PreHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, modifiedField))] public static void MySalesTable_Pre_modifiedField(XppPrePostArgs _args) { MySalesTable modBuffer = _args.getThis(); }

Post:

x++
[PostHandlerFor(tableStr(MySalesTable), tableMethodStr(MySalesTable, modifiedField))] public static void MySalesTable_Post_modifiedField(XppPrePostArgs _args) { MySalesTable modifiedRec = _args.getThis(); }

📊 DataSource Event Handlers

📥 Written

x++
[FormDataSourceEventHandler(formDataSourceStr(MySalesForm, SalesTable_DS), FormDataSourceEventType::Written)] public static void SalesTable_DS_OnWritten(FormDataSource _sender, FormDataSourceEventArgs _e) { FormRun frmRun = _sender.formRun(); FormDataSource ds = frmRun.dataSource(formDataSourceStr(MySalesForm, SalesTable_DS)) as FormDataSource; MySalesTable writtenRec = ds.cursor(); }

🆕 InitValue

x++
[FormDataSourceEventHandler(formDataSourceStr(MySalesForm, SalesTable_DS), FormDataSourceEventType::InitValue)] public static void SalesTable_DS_OnInitValue(FormDataSource _sender, FormDataSourceEventArgs _e) { FormRun myForm = _sender.formRun(); FormDataSource dsInit = myForm.dataSource(formDataSourceStr(MySalesForm, SalesTable_DS)) as FormDataSource; MySalesTable initRecord = dsInit.cursor(); }

🚦 Activated

x++
[FormDataSourceEventHandler(formDataSourceStr(MySalesForm, SalesTable_DS), FormDataSourceEventType::Activated)] public static void SalesTable_DS_OnActivated(FormDataSource _sender, FormDataSourceEventArgs _e) { MySalesTable activeCursor = _sender.cursor(); FormDataSource ds = _sender.formRun().dataSource("SalesTable_DS"); FormRun activeForm = _sender.formRun(); }

🔧 Initialized

x++
[FormDataSourceEventHandler(formDataSourceStr(MySalesForm, SalesTable_DS), FormDataSourceEventType::Initialized)] public static void SalesTable_DS_OnInitialized(FormDataSource _sender, FormDataSourceEventArgs _e) { FormDataSource initializedDS = _sender.formRun().dataSource("SalesTable_DS"); FormRun initializedForm = _sender.formRun(); }

🔐 ValidatingWrite

x++
[FormDataSourceEventHandler(formDataSourceStr(MySalesForm, SalesTable_DS), FormDataSourceEventType::ValidatingWrite)] public static void SalesTable_DS_OnValidatingWrite(FormDataSource _sender, FormDataSourceEventArgs _e) { var dsValidate = _sender as FormDataSource; var cancelArgs = _e as FormDataSourceCancelEventArgs; if (cancelArgs != null && dsValidate != null) { // Custom validation logic here } }

🖼️ Form-Level Event Handlers

📌 Initialized

x++
[FormEventHandler(formStr(MySalesForm), FormEventType::Initialized)] public static void MySalesForm_OnInitialized(xFormRun _sender, FormEventArgs _e) { FormDataSource salesDS = _sender.dataSource(formDataSourceStr(MySalesForm, SalesTable_DS)); }

Closing

x++
[FormEventHandler(formStr(MySalesForm), FormEventType::Closing)] public static void MySalesForm_OnClosing(xFormRun _sender, FormEventArgs _e) { FormDataSource closingDS = _sender.dataSource(formDataSourceStr(MySalesForm, SalesTable_DS)); MySalesTable closingRec = closingDS.cursor(); }

⚙️ Post Handler for init

x++
[PostHandlerFor(formStr(MySalesForm), formMethodStr(MySalesForm, init))] public static void MySalesForm_Post_init(XppPrePostArgs _args) { FormRun postInitForm = _args.getThis(); FormDesign design = postInitForm.design(); FormControl control1 = design.controlName(formControlStr(MySalesForm, ControlOne)); FormControl control2 = design.controlName(formControlStr(MySalesForm, ControlTwo)); }

🎯 Conclusion

With these rewritten and uniquely named event handler examples, you're now equipped to implement clean, maintainable, and extensible event-based logic in your D365FO customizations. These techniques let you hook into system events without overwriting base methods, keeping your extensions upgrade-safe.

Post a Comment

0 Comments