How to add handler to graph dynamically

Hello everybody,

today I want to describe how you can add events to your graph dynamically with usage of AddHandler method.

Take a look on a code sample taken from Acumatica approval maps:

public class EPApprovalAutomation<SourceAssignApprovedRejectedHoldSetupApproval> : 
  EPApprovalList<SourceAssign, Approved, Rejected>
  where SourceAssign : class, IAssign, IBqlTable, new()
  where Approved : class, IBqlField
  where Rejected : class, IBqlField
  where Hold : class, IBqlField
  where SetupApproval : class, IBqlTable, new()
{
  public EPApprovalAutomation(PXGraph graph, Delegate @delegate)
    : base(graph, @delegate)
  {
    this.Initialize(graph);
  }
 
  public EPApprovalAutomation(PXGraph graph)
    : base(graph)
  {
    this.Initialize(graph);
  }
 
  private void Initialize(PXGraph graph)
  {
    graph.FieldVerifying.AddHandler(BqlCommand.GetItemType(typeof (Approved)), typeof (Approved).Name, new PXFieldVerifying(this.Approved_FieldVerifying));
    graph.FieldVerifying.AddHandler(BqlCommand.GetItemType(typeof (Rejected)), typeof (Rejected).Name, new PXFieldVerifying(this.Rejected_FieldVerifying));
    graph.FieldUpdated.AddHandler(BqlCommand.GetItemType(typeof (Approved)), typeof (Approved).Name, new PXFieldUpdated(this.Approved_FieldUpdated));
    graph.FieldUpdated.AddHandler(BqlCommand.GetItemType(typeof (Rejected)), typeof (Rejected).Name, new PXFieldUpdated(this.Rejected_FieldUpdated));
    graph.FieldDefaulting.AddHandler(BqlCommand.GetItemType(typeof (Hold)), typeof (Hold).Name, new PXFieldDefaulting(this.Hold_FieldDefaulting));
    graph.FieldDefaulting.AddHandler(BqlCommand.GetItemType(typeof (Approved)), typeof (Approved).Name, new PXFieldDefaulting(this.Approved_FieldDefaulting));
    graph.Initialized += new PXGraphInitializedDelegate(this.InitLastEvents);
  }

 As you can see in the method Initialize, we setup in our own kind of view events for graphs, which will use our view.

In this example we add methods Apporved_FieldVerifying, Rejected_FieldVerifying, Approved_FieldUpdated, etc. 

And if to look on the implementation of the methods, it's quite obvious and have nothing special:

protected virtual void Approved_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
{
  boolnewValue = (bool?) e.NewValue;
  bool flag = true;
  if (newValue.GetValueOrDefault() == flag & newValue.HasValue && !this.IsApprover((SourceAssign) e.Row))
  {
    if (sender.GetAttributesReadonly<Approved>(e.Row).OfType<PXUIFieldAttribute>().Any<PXUIFieldAttribute>((Func<PXUIFieldAttribute, bool>) (attribute => attribute.Visible)))
      PXUIFieldAttribute.SetError<Approved>(sender, e.Row, "You are not an authorized approver for this document.");
    throw new PXSetPropertyException("You are not an authorized approver for this document.");
  }
  PXUIFieldAttribute.SetError<Approved>(sender, e.Row, (stringnull);
}

Which means, that you can use presented template for adding your methods inside of your view, in case if you need to accomplish that.

Also want to mention, that these dynamic methods, while adding to the sequences, will follow the rules below:

When calling the AddHandler<>() method, the collection of event handlers is updated according to the following rules:

  • For events with names ending in "ing" (excluding the RowSelecting event), new event handlers are added to the beginning of the collection.
  • For events with names ending in "ed" and the RowSelecting event, new event handlers are added to the end of the collection. To remove an event handler, you can use the RemoveHandler<>() method.

 

Summary

By using the AddHandler method, specific event handlers are attached to field verifying, field updated, and field defaulting events for different fields. The example demonstrates the implementation of methods such as Approved_FieldVerifying, Rejected_FieldVerifying, Approved_FieldUpdated, and more.

These dynamically added methods follow certain rules when added to the event handler collection. Events ending with "ing" (excluding RowSelecting) have handlers added to the beginning of the collection, while events ending with "ed" and the RowSelecting event have handlers added to the end of the collection. The RemoveHandler method can be used to remove event handlers when necessary.

By understanding this approach, you can apply similar techniques to add custom methods to your views, tailored to your specific requirements. This flexible and dynamic approach allows for efficient event handling within Acumatica.