置于Grid中的PXCustomSelectorAttribute自定义选择器无法自动刷新,求实现方法
嘿,我来帮你搞定这个自定义选择器自动刷新的问题!当你用PXCustomSelectorAttribute的时候,确实不像PXSelector那样有现成的AutoRefresh属性,但咱们有几种实用的办法能实现类似的效果,下面给你逐个拆解:
方法1:添加手动刷新按钮快速触发
最简单的方式是在页面上给自定义选择器加一个刷新按钮,用户点击就能重新加载选择器的数据源。在ASPX页面里添加如下代码:
<px:PXSelector runat="server" ID="edMyCustomField" DataField="MyCustomSelectorField" /> <px:PXRefreshButton runat="server" ID="btnRefreshSelector" CommandSourceID="edMyCustomField" />
这个按钮会直接绑定到选择器控件,点击后会清除选择器的缓存并重新获取最新数据,操作直观,适合不需要完全自动的场景。
方法2:关联字段变化时自动触发刷新
如果需要当其他字段的值改变时,自动刷新自定义选择器,可以在目标字段的FieldUpdated事件里手动刷新选择器的缓存。举个代码例子:
protected void MyDAC_RelatedField_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) { var currentRow = e.Row as MyDAC; if (currentRow == null) return; // 第一步:清除自定义选择器数据源的缓存 PXCache selectorCache = this.Caches[typeof(MySelectorDAC)]; // 替换成你的选择器数据源DAC selectorCache.Clear(); // 第二步:刷新当前字段的选择器状态,确保UI同步更新 PXSelectorState selectorState = PXSelectorAttribute.GetState(cache, currentRow, nameof(MyDAC.MyCustomSelectorField)) as PXSelectorState; if (selectorState != null) { selectorState.Cache.Clear(); selectorState.RaiseFieldChanged(); } }
这样只要RelatedField的值发生变化,自定义选择器就会自动重新加载最新的选项,完全不需要用户手动操作。
方法3:封装可复用的自动刷新自定义选择器属性
如果你的项目里多个地方都需要带自动刷新的自定义选择器,可以封装一个继承自PXCustomSelectorAttribute的扩展属性,把自动刷新的逻辑内置进去。代码示例如下:
public class PXAutoRefreshCustomSelectorAttribute : PXCustomSelectorAttribute { private readonly Type[] _triggerFields; // 构造函数:传入选择器类型和需要触发刷新的字段类型 public PXAutoRefreshCustomSelectorAttribute(Type selectorType, params Type[] triggerFields) : base(selectorType) { _triggerFields = triggerFields; } public override void CacheAttached(PXCache cache) { base.CacheAttached(cache); // 给每个触发字段绑定FieldUpdated事件 foreach (var fieldType in _triggerFields) { cache.FieldUpdated.AddHandler(fieldType, OnTriggerFieldUpdated); } } private void OnTriggerFieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e) { // 清除选择器数据源缓存 var selectorCache = sender.Graph.Caches[this.SelectorType]; selectorCache.Clear(); // 刷新当前选择器字段的UI状态 var selectorState = PXSelectorAttribute.GetState(sender, e.Row, this.FieldName) as PXSelectorState; selectorState?.RaiseFieldChanged(); } }
使用的时候就非常简洁了,指定选择器的数据源DAC和触发刷新的字段即可:
[PXAutoRefreshCustomSelector(typeof(MySelectorDAC), typeof(MyDAC.RelatedField1), typeof(MyDAC.RelatedField2))] public virtual int? MyCustomSelectorField { get; set; }
这样这个字段就会在RelatedField1或RelatedField2变化时自动刷新选择器选项,复用性拉满。
补充:如果能用PXSelector替代的话
如果你的自定义选择器逻辑可以通过PXSelectorAttribute的自定义查询实现(比如用Search或SubQuery),那直接用PXSelector自带的AutoRefresh属性会更省事:
[PXSelector( typeof(Search<MySelectorDAC.ID, Where<MySelectorDAC.Condition, Equal<Current<MyDAC.RelatedField>>>>), AutoRefresh = true, DescriptionField = typeof(MySelectorDAC.Description))] public virtual int? MySelectorField { get; set; }
但如果必须用PXCustomSelector来实现复杂逻辑,那前面的三种方法就完全够用啦。
内容的提问来源于stack exchange,提问作者Prathyusha

