【问题标题】:Acumatica Graph functionsAcumatica 图形函数
【发布时间】:2022-01-03 09:33:32
【问题描述】:

我已经用 acumatica 编程一年了,但我仍然不太明白某些事情是如何工作的。例如,在以下代码中图表如何工作,正在添加逻辑,但是,如果在基本方法之前添加此逻辑,我不明白如何将信息传递到下一页。我已经阅读了文档,但有时我仍然不明白,你知道我在哪里可以找到更好的信息吗?

public delegate IEnumerable createSalesOrder(PXAdapter adapter);

[PXOverride]
public virtual IEnumerable CreateSalesOrder(PXAdapter adapter, createSalesOrder baseMethod)
{
    PXTrace.WriteInformation("try ");

    PXGraph.InstanceCreated.AddHandler<SOOrderEntry>((graph) =>
    {
        graph.RowInserted.AddHandler<SOOrder>((sender, e) =>
        {
            SOOrder order = (SOOrder)e.Row;
            SOOrderExt orderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(order);

            orderExt.UsrCustomOne = "Howdy";  //assign anything you want here*/
        });
    });

    return baseMethod(adapter);
 }

很明显,一个事件处理程序被添加到一个图的实例中,但是它是如何专门将该信息传递给在基方法中创建的下一个对象,或者它是如何将此逻辑添加到新的排序

【问题讨论】:

    标签: c# asp.net acumatica acumatica-kb


    【解决方案1】:

    PXGraph.InstanceCreated 是静态属性;您正在创建图表之前设置事件处理程序。

    当您调用基本方法(使用return baseMethod(adapter))时,它将创建SOOrderEntry 图的新实例。在新实例的初始化过程中,图表将查找任何InstanceCreated 事件处理程序并调用代码,在您的情况下,这会将RowInserted 事件处理程序添加到新图表中。您的 InstanceCreated 处理程序将在回调期间有效。

    这是在涉及多个图表时自定义逻辑的最简洁方式(从机会创建订单、从订单创建装运等)。

    【讨论】:

      【解决方案2】:

      您的示例是在调用基本方法之前添加一个事件处理程序。在执行过程中,Acumatica 创建了具有定义扩展的基本元素的组合。由于您已经覆盖了基本方法,因此您的方法通过委托调用,然后您必须告诉 C# 是否/何时执行基本代码。如果您需要稍后执行代码,您可以在此代码的开头调用 baseMethod.Invoke(adapter),但在这种情况下,您明确告诉 C# 执行您的代码,然后运行基本方法。

      除非您的方法包含在非常旧的培训材料或非常新的培训材料中,否则您添加事件处理程序的方式对我来说有点陌生。我在标准代码中看到过类似的东西,但似乎并不常见。我记得的唯一一个例子是,有人建议我在代码中为不同的标准图形注入事件处理程序,该处理程序仅在使用我的图形时才需要做某事,而不是在标准屏幕执行图形代码时。我不确定事件处理程序本身是否在您的方法结束时自动删除,或者是否在每次执行该方法时都实例化它,因为我不使用您的方法。

      无论如何,在您的示例中发生的情况是在调用基本方法之前添加了事件处理程序,因为您告诉它在调用方法时创建事件处理程序,并且委托会导致您的覆盖首先执行。基方法在最后被调用,但只是因为你说要这样做。如果您没有明确告诉 C# 执行基本方法,委托将使您的代码执行并且永远不会运行基本代码。简而言之,它存在于委托/覆盖的机制中。

      我被训练这样添加事件处理程序的方式......

      using PX.Data;
      using PX.Objects.SO;
      
      namespace Blog
      {
          public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
          {
              public static bool IsActive() =>
                  Common.FeatureInstalled<Common.CMMSFeaturesSet.main>();
      
              protected virtual void _(Events.RowInserted<SOOrder> e, PXRowInserted baseEvent)
              {
                  SOOrder order = (SOOrder)e.Row;
                  SOOrderExt orderExt = PXCache<SOOrder>.GetExtension<SOOrderExt>(order);
      
                  orderExt.UsrCustomOne = "Howdy";  //assign anything you want here*/
      
                  if (baseEvent != null) baseEvent.Invoke(e.Cache, e.Args);
              }
      
          }
      }
      

      通过直接在图形扩展中定义它,它会使用图形扩展进行初始化,从而确保在插入行时触发事件。我怀疑您的代码要么仅在执行该方法时触发,要么在每次调用该方法时创建事件的多个实例。同样,我只是不太熟悉如何按您的方式添加事件处理程序。

      假设您添加事件处理程序的方法将其范围限定为添加它的方法,除非通过特定方法创建销售订单,否则它不会执行。如果它在添加后对于图形是持久的,那么在插入时添加 SOOrder 的任何其他方法都将无法调用您的事件处理程序,直到您的方法被调用以添加事件处理程序。

      【讨论】:

      • 我有时也会使用 PXGraph.InstanceCreated.AddHandler。它的一个优点是取决于您调用它的位置以及某些字段值的可用性。否则将不会通过图形扩展出现或可用。更重要的是,图形扩展事件总是会受到影响。而运行时处理程序仅在该特定图形实例的特定场景中处于活动状态。
      猜你喜欢
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 2017-10-18
      相关资源
      最近更新 更多