如何在运行时为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
相关产品推荐
相关产品推荐

