Customization of Field Attributes in DAC Extensions

If you have customization code that replaces the original attributes of a field with custom attributes, after you upgrade MYOB Acumatica to a new version, new functionality may became unavailable, as the following diagram shows.

Figure 1. Possible result of using the Replace (default) method to customize the attributes of a DAC field


To address this issue, the customization framework provides advanced possibilities for you to control the field customization by using additional attributes in the DAC extension.

When you customize MYOB Acumatica, you can specify how the system should apply the original and custom attributes to the field. Thus, you can make the customizations more flexible and use the collections of original attributes that could be updated between MYOB Acumatica versions.

To specify the way the system should apply the field attributes in a DAC extension, you can use the following attributes.
Attribute or Attributes Description
PXMergeAttributes The attribute specifies how to apply custom attributes to the existing ones.
PXRemoveBaseAttribute This attribute removes the specified existing attribute.

The following strong typed customization attributes of the PXCustomize static class:

All the listed attributes customize the specified attributes.

The PXCustomize static class also provides the PXCustomize.AnyAttributeAttribute attribute, which can be used to customize any attribute derived from the PXEventSubscriberAttribute attribute. However, we recommend that you instead use the listed strongly typed customization attributes wherever possible.

Tip: You can also use the listed strongly typed customization attributes to customize the descendants of their target attributes. For example, you can use the PXCustomize.PXDBFieldAttributeAttribute attribute to customize the PXDBIntAttribute and PXDBStringAttribute attributes, which are descendants of the PXDBFieldAttribute attribute.
PXCustomizeSelectorColumns This attribute defines the new set and order of the columns in the selector.
Tip: The double Attribute suffix (such as PXCustomize.PXUIFieldAttributeAttribute in the example below) is dropped from the name of the customization attribute when you use it in code. This is intentional, as it makes it easy for you to recognize the attribute that the customization attribute is targeting because it mirrors the name of the targeted attribute.

In the following example, the display name of the MyField field of the MyDac DAC is My Field, and in the MyDacExt DAC extension the display name of this field is changed to My Custom Field.

public class MyDac : PXBqlTable, IBqlTable
{
   public abstract class myField: PX.Data.BQL.BqlInt.Field<myField> { }
   [PXDBInt]
   [PXUIField(DisplayName = "My Field")]
   public virtual int? MyField{ get; set; }
}

public class MyDacExt : PXCacheExtension<MyDac>
{
  [PXCustomize.PXUIFieldAttribute(DisplayName = "My Custom Field")]
  public virtual int? MyField{ get; set; }
}
Tip: The code example above uses the strongly typed PXCustomize.PXUIFieldAttributeAttribute attribute to customize PXUIFieldAttribute. Alternatively, you can use the PXCustomize.AnyAttributeAttribute attribute, as shown in the following code example. However, we recommend that you use the strongly typed customization attributes wherever possible.
public class MyDac : PXBqlTable, IBqlTable
{
   public abstract class myField: PX.Data.BQL.BqlInt.Field<myField> { }
   [PXDBInt]
   [PXUIField(DisplayName = "My Field")]
   public virtual int? MyField{ get; set; }
}

public class MyDacExt : PXCacheExtension<MyDac>
{
  [PXCustomize.AnyAttribute(typeof(PXUIFieldAttribute), 
    nameof(PXUIFieldAttribute.DisplayName), "My Custom Field")]
  public virtual int? MyField{ get; set; }
}

Application Order of the Custom Attributes

The customization attributes described above are applied in the following order:

  1. Customization attributes of the PXCustomize static class
  2. PXRemoveBaseAttribute
  3. PXMergeAttributes
Tip: The PXCustomizeSelectorColumns works independently of these three attributes.

For details on how to customize field attributes for a particular screen, see the Overriding Attributes of a DAC Field in the Graph topic.

Adding an Attribute to an Existing DAC Field

Suppose that you have a DAC and a DAC extension, and in the DAC extension, you need to add an attribute to the set of inherited attributes of a DAC field. In that case, you’ll need to override the whole property, including the virtual field and the abstract class, and define all attributes from scratch. The customization attributes described in the previous section are not applicable.

For an auto-implemented property in the parent DAC, you define the auto-implemented property in the DAC extension. For a full property in the parent DAC, you define the full property in the DAC extension. For example, suppose that you have the following property in the parent DAC.

public virtual int? MyProp
{
    get => _FieldValue;
    set => _FieldValue = value;
}

The overridden property should look as shown in the following code.

public override int? MyProp
{
    get => base.MyProp;
    set => base.MyProp = value;
}