You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

置于Grid中的PXCustomSelectorAttribute自定义选择器无法自动刷新,求实现方法

实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:28:38