To extend a form in D365 for Operations, we can use pre-defined events and form delegates. Event handler methods on a handler class can be assigned to them to be called when the event is triggered (For more info, see my previous post AX7 Extensibility – Part 3 : Event handlers and delegates (hooks)). As you know static methods can be called without creating a class instance and cannot access its class instance variables.

What if we need to access a class instance variable within these static event handlers?Like for example, the ‘counter’ variable below within the handler class?

final class TSExtensionInstanceTestHandler
{
    private int counter;

    [FormControlEventHandler(formControlStr(TSExtensionInstanceTest, Counter), FormControlEventType::Clicked)]
    public static void Toggle_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        FormRun formRun = sender.formRun();
    }
    [FormControlEventHandler(formControlStr(TSExtensionInstanceTest, Test), FormControlEventType::Clicked)]
    public static void Test_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        FormRun formRun = sender.formRun();
    }
}


D365 fo forms have a possibility to register and recall extension class instances inside them. This way you can create a class instance, register it inside the formrun and access the instance in any of the static event handlers by calling “getExtensionInstance” method. Let’s do a simple example, creating a form with two buttons, “Counter” and “Test”, in which counter button will count and test button will display the counter value, and put all the logic in an event handler class.

CaptureExtForm.PNG

first add a constructor to your class with caller formrun as a parameter :

    public void new(FormRun _formRunInstance)
    {
        FormRun element = _formRunInstance;

element.registerExtensionInstance(classStr(TSExtensionInstanceTestHandler), this);
    }

Then add an init method to your event handler class:

private void init()
    {
        counter = 0;
    }

Then we need to call our constructor and afterwards initialize our class instance, for that we use form’s ‘Initializing’ and ‘Initialized’ events :

    [FormEventHandler(formStr(TSExtensionInstanceTest), FormEventType::Initializing)]
    public static void TSExtensionInstanceTest_OnInitializing(xFormRun sender, FormEventArgs e)
    {
        TSExtensionInstanceTestHandler extensionInstance = new TSExtensionInstanceTestHandler(sender);
    }

    [FormEventHandler(formStr(TSExtensionInstanceTest), FormEventType::Initialized)]
    public static void TSExtensionInstanceTest_OnInitialized(xFormRun sender, FormEventArgs e)
    {
        FormRun formRun = sender as FormRun;
        TSExtensionInstanceTestHandler extensionInstance = formRun.getExtensionInstance(classStr(TSExtensionInstanceTestHandler));
        extensionInstance.init();
    }

Then we can use formRun’s “getExtensionInstance” method to access our class instance in our event handler methods:

	public int increaseCounter()
    {
        counter++;
        return counter;
    }

    public int getCounter()
    {
        return counter;
    }

    [FormControlEventHandler(formControlStr(TSExtensionInstanceTest, Counter), FormControlEventType::Clicked)]
    public static void Counter_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        FormRun formRun = sender.formRun();

        TSExtensionInstanceTestHandler extensionInstance = formRun.getExtensionInstance(classStr(TSExtensionInstanceTestHandler));
        extensionInstance.increaseCounter();

    }

    [FormControlEventHandler(formControlStr(TSExtensionInstanceTest, Test), FormControlEventType::Clicked)]
    public static void Test_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        FormRun formRun = sender.formRun();

        TSExtensionInstanceTestHandler extensionInstance = formRun.getExtensionInstance(classStr(TSExtensionInstanceTestHandler));
        info(strFmt("Counter value : %1", extensionInstance.getCounter()));
    }

CaptureFormFinal.PNG

Today instead of this construction, it is much better to use chain of command methods, but in case you want to use event handlers only, or update any older code, this is how you can use event handlers with class instance variables.

For more information and to see an example by Microsoft, you can check out the following AX class :

“HcmPositionFormExtensionPayrollHandler”

You can download the demo project for this blog post from the following GitHub link :

https://github.com/sertanyaman/SertanDevAXExamples/blob/master/ExtensionInstanceTest.axpp

 

 

[adinserter block=”9″]

 

Leave a Reply