Adding an event handler to a native control

I am working on a little form customisation where I want code to be run when a field value changes. I have tried a form event handler, but this gave inconsistent results as to whether the form event would fire or not. The event wizard for controls doesn’t allow event handlers to be put on native controls only on custom controls.
I have seen some code samples adding the event handler directly in the script. Is this a safe thing to do given that the wizard doesn’t give the option.?

I’ve had to hide the native controls on occasion, then put a custom controls in their place. (make sure to remove the tab stop before you hide it) Some controls are easy to replace with a custom one. Then you can use the Form Event Wizard.

I did it the other way round, Marjorie. I created a databound custom control that is hidden off the edge of the form. Just seems rather messy to me that events aren’t easily available on native controls

You can make event handlers for native controls. Just make sure to do everything the Wizard does.

edit

Here’s the steps.

  1. Declare an object of the type of the native control. Put this right below // Add Custom Module Level Variables Here **
public EpiTextBox txtPONum; //e5d73cb9-1d94-45ce-85be-db4c85fe3264
  1. Create initialze call in public void InitializeCustomCode(). Reference the native controls GUID.
txtPONum = (EpiTextBox)csm.GetNativeControlReference("e5d73cb9-1d94-45ce-85be-db4c85fe3264");
this.txtPONum.Click += new System.EventHandler(this.txtPONum_Click);
  1. Create destroy call in public void DestroyCustomCode().
		// Begin Custom Code Disposal
		this.txtPONum.Click -= new System.EventHandler(this.txtPONum_Click);
		// End Custom Code Disposal
  1. Create the handler function
private void txtPONum_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
	}

This might be easier to do if you add a custom control of the same type, use the event wizard to make the code for it, then go back and change the references in the wizard created code to be for the native control. You’ll need to manually add the line for GetNativeControlReference

6 Likes

Thank you. I wll have a play when I get some time. Epicor customisation is such a tedious experience if you want to do some experimenting!

I guess adding events to standard controls is discouraged as you should be using the Epicor framework e.g. use the AfterFieldChange event. Way I look at it is classic control events are the domain of WInForms apps, however we are working with an Epicor framework should should be doing it the framework way. Of course, that is the ideal that doesnt always fit real life :slight_smile: - for example, AfterFieldChange does not fire when a new record is loaded, whereas control.ValueChanged does.

Some fields may be bound to more than one control (for example may appear on a [Summary] and a [Header] tab) and by using field changed you catch 'em all. As a general rule, if tying traditional WinForms events on base controls then probably doing it wrong (though not always I grant you). OP mentioned inconsitant results using the Wizard method, what were the issues ?

Pretty much as you say, Jon.
I originally tried the AfterFieldChange event and it didn’t always fire. Load a record - fine. Load another record - fine. navigate between the loaded records - no events.

Epicor have essentially given up on win form customisation. The Infragistics library still used is many versions out of date. The future at the moment is Kendo UI I assume. After the pains of E9-E10 ABL conversion next comes customised form conversion in later releases of Epicor??

@Jon_Evans got me thinking about the dangers of hooking into / intercepting events of native controls.

If the form already has an event handler for a native control, and I manually make my own (of the same event type), does mine replace the original one? Or does it create another function that would be called after the original one?

The code:

this.txtPONum.Click += new System.EventHandler(this.txtPONum_Click);

uses the += operation, which means “add to the existing”.

If I had the following code:

this.txtPONum.Click += new System.EventHandler(this.txtPONum_Click);
this.txtPONum.Click += new System.EventHandler(this.txtPONum_Click_2);

with the two functions: this.txtPONum_Click() and this.txtPONum_Click_2(), would a click of the control txtPONum call both functions, or just the second?

If it did call both, would changes to the agruments within the first function be reflected in second?

1 Like

During an invocation, methods are invoked in the order in which they appear in the invocation list. A delegate attempts to invoke every method in its invocation list; duplicates are invoked once for each time they appear in the invocation list. …-snip- … When the signature includes a parameter that is passed by reference, the final value of the parameter is the result of every method in the invocation list executing sequentially and updating the parameter’s value.

You can have multiple handlers. They are executed in the order they are registered.

1 Like

I think that is a good point to raise, Calvin.

Would debug reveal what is set on a ‘click’ property?

See @Evan_Purdy’s reply

This worked perfectly, Thank you Calvin