【问题标题】:Populating unbound field from another bound custom field从另一个绑定的自定义字段填充未绑定字段
【发布时间】:2018-01-12 03:35:41
【问题描述】:

我需要在 SalesOrder 屏幕上有一个字段,并且相同的字段也应该出现在各个 SalesOrder 的 Shipment 屏幕上。并且用户应该能够在两个屏幕上更新这些字段。

我在销售订单屏幕上创建了一个绑定字段,用户可以保存它。然后我在发货屏幕上创建了一个未绑定字段来显示销售订单中的文本。为此,我编写了一个 SOShipment_RowSelected 事件,后来为了让用户将其更新到数据库,我编写了 SOShipment_RowUpdated。但是,当我尝试编辑该字段时,它会触发 RowSelected 事件并覆盖编辑并返回相同的原始值。

我已尝试使用 SOShipment_ShipmentNbr_FieldUpdated 和 SOShipment_ShipmentNbr_FieldUpdating 事件,但不是每次都触发。

这里是缓存扩展的代码-

public class SOOrderExtension : PXCacheExtension<SOOrder>
{
	#region UsrNotesText
	[PXDBString(255)]
	[PXUIField(DisplayName = "Pick List Notes")]
	public virtual string UsrNotesText { get; set; }
	public abstract class usrNotesText : IBqlField { }
	#endregion
}
	
public class SOShipmentExtension : PXCacheExtension<SOShipment>
{
	#region UsrNotesText
	[PXString(255)]
	[PXUIField(DisplayName = "Pick List Notes")]
	public virtual string UsrNotesText { get; set; }
	public abstract class usrNotesText : IBqlField { }
	#endregion
}

SOSshipment扩展代码-

public class SOShipmentEntryExtension : PXGraphExtension<SOShipmentEntry>
{
	PXSelect<SOOrder> soOrder;

	protected virtual void SOShipment_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
	{
		if (e.Row != null)
		{
			SOOrder order = PXSelectJoin<SOOrder,
				LeftJoin<SOOrderShipment, On<SOOrder.orderNbr, Equal<SOOrderShipment.orderNbr>,
					And<SOOrder.orderType, Equal<SOOrderShipment.orderType>>>,
				LeftJoin<SOShipment, On<SOOrderShipment.shipmentNbr, Equal<SOShipment.shipmentNbr>>>>,
				Where<SOShipment.shipmentNbr, Equal<Current<SOShipment.shipmentNbr>>>>.Select(Base);

			if (order != null)
			{
				SOOrderExtension orderExt = PXCache<SOOrder>.GetExtension<SOOrderExtension>(order);

				SOShipment soShipment = Base.Document.Current;

				SOShipmentExtension ext = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(soShipment);
				ext.UsrNotesText = orderExt.UsrNotesText;
			}
		}
	}

	protected virtual void SOShipment_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
	{
		SOShipment oldRow = (SOShipment)e.OldRow;
		SOShipment newRow = (SOShipment)e.Row;

		if (oldRow != null || newRow != null)
		{
			SOShipmentExtension oldExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(oldRow);
			SOShipmentExtension newExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(newRow);


			if (oldExt.UsrNotesText != newExt.UsrNotesText)
			{
				{
					SOOrder order = PXSelectJoin<SOOrder,
					LeftJoin<SOOrderShipment, On<SOOrder.orderNbr, Equal<SOOrderShipment.orderNbr>,
						And<SOOrder.orderType, Equal<SOOrderShipment.orderType>>>,
					LeftJoin<SOShipment, On<SOOrderShipment.shipmentNbr, Equal<SOShipment.shipmentNbr>>>>,
					Where<SOShipment.shipmentNbr, Equal<Current<SOShipment.shipmentNbr>>>>.Select(Base);

					soOrder.Current = order;

					if (order != null)
					{
						SOOrderExtension orderExt = PXCache<SOOrder>.GetExtension<SOOrderExtension>(order);

						orderExt.UsrNotesText = newExt.UsrNotesText;
						soOrder.Update(order);
					}
				}
			}
		}
	}
}

有什么建议吗?

【问题讨论】:

  • RowSelected 不是数据更新的好地方。应该只用于 UI 内容,例如可见、启用等。RowInserted 怎么样?
  • RowInserted 也不起作用。我认为只有在为主 DAC 插入新行时才会触发。我知道 RowSelected 不是设置一些默认值的好地方,但是由于某种原因,没有其他事件对我有用。
  • 如果一切都失败了,SOSshipment_UsrNotesText_FieldSelecting 应该这样做。
  • 问题是没有触发此类事件。我正在使用 Acumatica 版本 17.203.0029,该事件是否有任何问题。
  • 我从来没有触发过FieldSelecting。事实上,它通常是大多数事件问题的最后解决方案。仔细检查语法: public void SOShipment_UsrNotesText_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)

标签: acumatica


【解决方案1】:

诀窍是在别处初始化 UsrNotesText。

您可以使用 PXDefault 属性:

[PXDefault(typeof(Search<SOOrderExtension.usrNotesText, Where< [...] >>))]

或 FieldDefaulting 事件处理程序:

public void SOShipment_UsrNotesText_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
   e.NewValue = [...]
}

有时您还希望在用户更改未重新触发默认值的关键字段时重新初始化。:

public void SOShipment_ShipmentNbr_FieldUpdated(PXCache sender, PXFieldDefaultingEventArgs e)
{
    SOShipment shipment = e.Row as SOShipment;

    if (shipment != null)
    {
        SOShipmentExtension shipmentExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(shipment);

        if (shipmentExt != null)
        {
            shipmentExt.UsrNotesText = [...];
        }
    }
}

在这种情况下,使用 RaiseFieldDefaulting 手动重新触发 FieldDefaulting 事件通常是更好的选择。

但是,您选择初始化的方法避免在 RowSelected 中设置字段值,因为有时会在您不想初始化自定义字段时调用该事件。

【讨论】:

  • SOSshipment_UsrNotesText_FieldDefaulting 事件未触发。我是否需要进行一些其他更改才能使其触发?
  • DAC 字段是否有 [PXDefault] 属性?
  • PXCache的RaiseFieldDefaulting方法也可以用来触发事件。
  • 我在 DAC 字段上没有 PXDefault 属性。另外,即使我想使用 RaiseFieldDefaulting 方法来触发,我应该在哪里编写该代码来触发。
  • 这取决于你想如何处理这个问题。简单的方法是将 [PXDefault] 属性添加到 DAC 字段,以便框架调用 FieldDefaulting 事件。如果出于某种原因您不想使用 PXdefault 事件框架,那么您可以在 FieldSelecting 事件中使用 RaiseFieldDefaulting,但这将非常愚蠢,因为它对设置 [PXDefault] 没有任何用处。您也可以在 FieldSelecting 中初始化您的值。出于语义原因,我认为 FieldDefaulting 更合适。
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多