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

如何在运行时为Acumatica GridView动态添加技能列

动态添加技能列到人员列表Grid的问题解决

我有三个DAC:People(PeopleID、Name)、Skills(SkillID、Name)和SkillValues(PeopleID、SkillID、Value)。要求添加一条Skills记录时,对应的列要自动出现在展示People列表的Graph Grid中。我写了如下代码,但没能成功添加列,不过页面加载时代码确实会执行,我觉得这个功能应该是可以实现的。

public class MyGraph: PXGraph<MyGraph>
{
    public MyGraph()
    {
        AddSkillColumns(MasterView.Cache);
    }

    private void AddSkillColumns(PXCache sender)
    {
        PXResultset<Skills> rows = SelectFrom<Skills>.View.Select(this);
        foreach (Skills row in rows)
        {
            String key = String.Format("Comp_{0}",row.SkillID.ToString());
            if(!sender.Fields.Contains(key))
            {
                sender.Fields.Add(key);
                this.FieldSelecting.AddHandler("MasterView", key, (PXCache cache, PXFieldSelectingEventArgs args) =>
                {

                });
                this.FieldUpdating.AddHandler("MasterView", key, (PXCache cache, PXFieldUpdatingEventArgs args) =>
                {

                });
            }
        }
    }

    public SelectFrom<People>.View.ReadOnly MasterView;
}

问题分析与修正方案

原代码仅给Cache添加了字段,但未配置字段显示属性、未绑定实际数据,同时Grid也未设置自动识别动态字段。以下是完整的修正实现:

1. 修正后的Graph代码

public class MyGraph : PXGraph<MyGraph>
{
    public SelectFrom<People>.View.ReadOnly MasterView;
    public PXSelect<SkillValue> SkillValue_Cache;

    public MyGraph()
    {
        // 延迟执行确保Cache完全初始化
        PXTimeProcessor.ScheduleTask(0, () => AddSkillColumns(MasterView.Cache));
    }

    private void AddSkillColumns(PXCache sender)
    {
        var skills = SelectFrom<Skills>.View.Select(this);
        foreach (Skills skill in skills)
        {
            string fieldKey = $"Comp_{skill.SkillID}";
            if (!sender.Fields.Contains(fieldKey))
            {
                // 添加动态字段到Cache
                sender.Fields.Add(fieldKey);
                
                // 配置字段显示属性,指定列标题为技能名称
                sender.SetAttributes(fieldKey, new PXUIFieldAttribute { DisplayName = skill.Name });
                // 根据SkillValue.Value的类型配置字段格式,这里假设是decimal
                sender.SetAttributes(fieldKey, new PXDecimalAttribute(2));

                // 绑定字段数据读取逻辑
                FieldSelecting.AddHandler<People>(fieldKey, (cache, args) =>
                {
                    People person = args.Row as People;
                    if (person == null) return;

                    // 查询当前人员对应的该技能值
                    SkillValue skillValue = SelectFrom<SkillValue>
                        .Where<SkillValue.peopleID.IsEqual<@P.AsInt>>
                        .And<SkillValue.skillID.IsEqual<@P.AsInt>>
                        .View.SelectSingle(this, person.PeopleID, skill.SkillID);

                    args.ReturnValue = skillValue?.Value;
                });

                // 绑定字段数据更新逻辑
                FieldUpdating.AddHandler<People>(fieldKey, (cache, args) =>
                {
                    People person = args.Row as People;
                    if (person == null) return;

                    // 查找或创建SkillValue记录
                    SkillValue skillValue = SelectFrom<SkillValue>
                        .Where<SkillValue.peopleID.IsEqual<@P.AsInt>>
                        .And<SkillValue.skillID.IsEqual<@P.AsInt>>
                        .View.SelectSingle(this, person.PeopleID, skill.SkillID);

                    if (skillValue == null)
                    {
                        skillValue = new SkillValue
                        {
                            PeopleID = person.PeopleID,
                            SkillID = skill.SkillID
                        };
                        skillValue = SkillValue_Cache.Insert(skillValue);
                    }

                    skillValue.Value = (decimal)args.NewValue;
                    SkillValue_Cache.Update(skillValue);
                });
            }
        }
    }
}

2. ASPX页面Grid配置

确保Grid开启自动生成列,让动态字段自动渲染为列:

<px:PXGrid ID="grid" runat="server" DataSourceID="ds" Width="100%" AutoGenerateColumns="True">
    <Levels>
        <px:PXGridLevel DataMember="MasterView">
            <Columns>
                <!-- 保留固定列 -->
                <px:PXGridColumn DataField="PeopleID" />
                <px:PXGridColumn DataField="Name" />
                <!-- 动态列将自动生成 -->
            </Columns>
        </px:PXGridLevel>
    </Levels>
</px:PXGrid>

关键注意点

  • 字段属性配置:必须添加PXUIFieldAttribute指定显示名称,否则Grid无法识别列标题;根据字段类型添加对应格式属性(如PXDecimalAttribute)。
  • 数据绑定逻辑:FieldSelecting事件中必须查询SkillValue表获取对应人员的技能值,否则列会显示为空;FieldUpdating事件中要处理记录的创建与更新,确保数据持久化。
  • Cache初始化时机:构造函数中直接调用AddSkillColumns可能因Cache未完全初始化导致失败,改用PXTimeProcessor.ScheduleTask延迟执行确保Cache就绪。
  • Grid自动生成列:ASPX中Grid必须设置AutoGenerateColumns="True",否则动态添加的字段不会渲染为Grid列。

内容的提问来源于stack exchange,提问作者Martin Weber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:25:02