使用 CacheAttached 覆盖图中的 DAC 属性

有时,你需要为特定屏幕覆盖特定数据访问类(DAC)字段的一个或多个属性,而不更改其他屏幕的现有行为。

替换所有属性

假设原始 DAC 字段属性声明如下:

public class ARInvoice : IBqlTable
{
    [PXDBDecimal(4)]
    [PXDefault(TypeCode.Decimal, "0.0")]
    [PXUIField(DisplayName = "Commission Amount")]
    public virtual Decimal? CommnAmt 
    { 
        get; 
        set; 
    }
}

覆盖图中字段属性的基本方法是在图中声明 CacheAttached 事件处理程序,该处理程序遵循命名图事件的标准约定(请注意缺少 EventArgs 参数)。事件处理程序的主体将不会被执行,但是你在处理程序上放置的任何属性都将替换相应 DAC 字段上的属性:

[PXDBDecimal(4)]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Commission Amount")]
[PXAdditionalAttribute(NecessaryProperty = true)]
protected virtual void ARInvoice_CommnAmt_CacheAttached(PXCache sender) { }

向 DAC 字段添加新属性

放置在 CacheAttached 处理程序上的属性集重新定义放置在 DAC 中的字段上的整个属性集。这几乎总是矫枉过正; 请注意,在前面的示例中,为了只向字段添加单个属性,你必须从 DAC 复制所有其他属性声明。这导致不希望的代码重复,以及 DAC 和图形不同步的可能性。很容易想象当某人改变 DAC 中的 PXDefaultAttribute 的默认逻辑时的情况,但忘记更新各种图中 CacheAttached 处理程序上的所有相应属性。

为了解决这个问题,Acumatica 框架提供了一个名为 PXMergeAttributesAttribute 的特殊属性。将此属性放在 CacheAttached 处理程序上时,你可以重用 DAC 中定义的现有属性。

使用 PXMergeAttributesAttribute 追加属性:

[PXMergeAttributes(Method = MergeMethod.Append)]
[PXAdditionalAttribute(NecessaryProperty = true)]
protected virtual void ARInvoice_CommnAmt_CacheAttached(PXCache sender) { }

在上面的示例中,将重用原始 DAC 中的整个属性集,并附加你在​​CacheAttached 事件处理程序上声明的任何属性。

PXMergeAttributesAttribute 具有其他合并行为,根据 Method 属性的以下可能值:

  • MergeMethod.Replace 完全取代了 DAC 的属性(相当于没有 PXMergeAttributesAttribute)。
  • MergeMethod.AppendCacheAttached 处理程序的属性附加到原始 DAC 属性。
  • MergeMethod.Merge 类似于 Append; 但是,它还会检查处理程序属性和 DAC 字段属性之间是否存在任何冲突属性。如果存在冲突,则 CacheAttached 属性优先,并丢弃相应的 DAC 属性。

覆盖属性的单个属性

当你必须仅为特定屏幕重新定义 DAC 属性的单个属性时,会出现一种非常常见的应用程序开发方案; 在必须定义 PXUIFieldAttribute 的 DisplayName 属性时考虑这种情况。

为此,你可以使用 Acumatica 框架提供的另一个特殊属性:PXCustomizeBaseAttributeAttribute。它的构造函数接受三个值:

  • 需要覆盖其属性的 DAC 属性的类型
  • 要覆盖的属性的属性名称(在 C#6.0 中使用 nameof 运算符以实现代码可维护性)
  • 指定属性的新值。

假设需要仅在一个屏幕上将 UI 显示名称从 Commission Amount 更改为 Base Currency Commission 。以下代码示例演示如何实现所需的行为。

[PXMergeAttributes(Method = MergeMethod.Append)]
[PXCustomizeBaseAttribute(typeof(PXUIFieldAttribute), nameof(PXUIFieldAttribute.DisplayName), "Base Currency Commission")]
protected virtual void ARInvoice_CommnAmt_CacheAttached(PXCache sender) { }

在此示例中,PXMergeAttributes 确保保留原始 DAC 属性,PXCustomizeBaseAttribute 允许软件工程师覆盖相关图形的 UI 字段的显示名称。

用另一个属性替换属性

假设只需要一个屏幕就需要用 PXDBDefaultAttribute 替换 DAC 字段的 PXDefaultAttribute

这可以通过以下方式实现:

[PXMergeAttributes(Method = MergeMethod.Append)]
[PXRemoveBaseAttribute(typeof(PXDefaultAttribute))]
[PXDBDefault(typeof(SOShipment.siteID), PersistingCheck = PXPersistingCheck.Nothing)]
protected void SOOrderShipment_SiteID_CacheAttached(PXCache sender) { }

属性自定义属性的应用顺序

  1. PXCustomizeBaseAttribute
  2. PXRemoveBaseAttribute
  3. PXMergeAttributes