【问题标题】:Dynamically changing PXSelector in Acumatica在 Acumatica 中动态改变 PXSelector
【发布时间】:2016-08-31 10:35:21
【问题描述】:

我有以下用例:

Acumatica 组合框/下拉列表,可以有 8 个左右的值,其选择决定了用于在 PXSelector 中呈现的表格/DAC。

例如:

-如果用户选择选项 a,我需要在表 A 中显示 PXSelector 值

-如果用户选择选项 b,我需要在表 B 中显示 PXSelector 值

-如果用户选择选项 c,我需要在表 C 中显示 PXSelector 值

我知道我必须使用自定义选择器属性,但具体如何执行此操作尚不清楚。

【问题讨论】:

    标签: c# acumatica


    【解决方案1】:

    如你所说,你需要实现一个继承自 PXCustomSelectorAttribute 类的属性。

    1- 创建一个 PromptType 类,该类将包含一个 IDDescription 来保存每个表的类型。

    public class PromptType
    {
        public Type Id { get; set;}
        public Type Description { get; set; }
    }
    

    2- 实现 customSelectorAttribute,如下所示:

    public class MyCustomSelector : PXCustomSelectorAttribute
    {
        //Class used to display the data into the selector
        [Serializable]
        public class TableDummy : IBqlTable
        {
            #region Id
    
            [PXInt(IsKey = true)]
            [PXUIField(DisplayName = "Id")]
            public int? Id { get; set; }
    
            public class id : IBqlField { }
    
            #endregion
    
    
            #region Description
    
            [PXString(60, IsUnicode = true, InputMask = "")]
            [PXUIField(DisplayName = "Description", Visibility = PXUIVisibility.SelectorVisible)]
            public string Description { get; set; }
    
            public class description : IBqlField { }
    
            #endregion
        }
    
        //Selected table
        private Type _TableSelection;
    
        //Tables Ids. You can add as much field ID as you want
        private Type _TableFieldA;
        private Type _TableFieldB;
        private Type _TableFieldC;
    
        //Tables description fields
        private Type _TableAFieldDesc;
        private Type _TableBFieldDesc;
        private Type _TableCFieldDesc;
    
    
        public MyCustomSelector(Type tableSelection, Type tableFieldA, Type tableAFieldDesc, Type tableFieldB, Type tableBFieldDesc, Type tableFieldC, Type tableCFieldDesc) : base(typeof(TableDummy.id))
        {
            _TableSelection = tableSelection;
            _TableFieldA = tableFieldA;
            _TableFieldB = tableFieldB;
            _TableFieldC = tableFieldC;
            _TableAFieldDesc = tableAFieldDesc;
            _TableBFieldDesc = tableBFieldDesc;
            _TableCFieldDesc = tableCFieldDesc;
        }
    
        //Get the name of the selected table by using the private field _TableSelection.
        private string GetSelection()
        {
            var cache = _Graph.Caches[_BqlTable];
            return cache.GetValue(cache.Current, _TableSelection.Name)?.ToString();
        }
    
        //Return a pompt instance based on the selected table in the dropdown.
        private PromptType GetSelectedTableField(string selectedTable)
        {
            switch (selectedTable)
            {
                case "A":
                    return new PromptType() { Id = _TableFieldA, Description = _TableAFieldDesc };
                case "B":
                    return new PromptType() { Id = _TableFieldB, Description = _TableBFieldDesc };
                case "C":
                    return new PromptType() { Id = _TableFieldC, Description = _TableCFieldDesc };
                default:
                    return new PromptType() { Id = _TableFieldA, Description = _TableAFieldDesc };
            }
        }
    
        //Return the records
        public IEnumerable GetRecords()
        {
            var selectedField = GetSelectedTableField(GetSelection());
            var selectedTable = BqlCommand.GetItemType(selectedField.Id);
    
            var select = BqlCommand.Compose(
                            typeof(Select<>),
                                selectedTable
                            );
    
            var cmd = BqlCommand.CreateInstance(select);
            PXView view = new PXView(_Graph, true, cmd);
    
            foreach (var row in view.SelectMulti())
            {
                var id = (int?)view.Cache.GetValue(row, selectedField.Id.Name);
                var description = view.Cache.GetValue(row, selectedField.Description.Name)?.ToString();
                yield return new TableDummy { Id = id, Description = description };
            }
        }
    }
    

    您可以通过传递所需数量的表来更改自定义属性的构造函数。


    3- 实现自定义属性后,您可以在字段中使用它,如下所示:

    #region DropDown to select a table
    [PXDBString(1)]
    [PXUIField(DisplayName = "Table Selection")]
    [PXStringList(
        new string[]
        {
            "A",
            "B",
            "C"
        },
        new string[]
        {
                "Table A",
                "Table B",
                "Table C"
        })]
    public virtual string UsrTableSelection { get; set; }
    public abstract class usrTableSelection : IBqlField
    {
    }
    #endregion
    
    #region Selector
    [PXDBInt]
    [PXUIField(DisplayName = "Table Selector")]
    [MyCustomSelector(
        typeof(APRegisterExt.usrTableSelection), 
        typeof(TableA.id),typeof(TableA.description),
        typeof(TableB.id), typeof(TableB.description),
        typeof(PX.Objects.AR.Customer.bAccountID), 
        typeof(PX.Objects.AR.Customer.acctName))]
    public virtual int? UsrTableSelector { get; set; }
    
    public abstract class usrTableSelector : IBqlField
    {
    }
    #endregion
    

    4- 此外,您不应忘记设置表格字段的可见性。我指的是要在选择器中显示的表格 (DACs)。假设您要根据您的下拉菜单显示TableATableBTableC,您需要设置要在选择器中使用的字段的可见性。

    这是我在测试期间使用的一张表的实现:

    [Serializable]
    public class TableA : IBqlTable
    {
        #region Id
    
        [PXDBInt(IsKey = true)]
        [PXUIField(DisplayName = "Id")]
        public int? Id { get; set; }
    
        public class id : IBqlField { }
    
        #endregion
    
    
        #region Description
    
        [PXDBString(60, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Description", Visibility = PXUIVisibility.SelectorVisible)]
        public string Description { get; set; }
    
        public class description : IBqlField { }
    
        #endregion
    
    
        #region InfoA
    
        [PXDBString(60, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Info A", Visibility = PXUIVisibility.SelectorVisible)]
        public string InfoA { get; set; }
    
        public class infoA : IBqlField { }
    
        #endregion
    }
    

    通过将可见性设置为SelectorVisible,该字段将自动显示在 PXSelector 中。


    5- 最后,您需要在下拉列表中将CommitChanges 设置为True,并在表单字段中将AutoRefresh 设置为True。这是一个例子:

    <px:PXDropDown runat="server" ID="CstPXDropDown1" DataField="UsrTableSelection" CommitChanges="True" />
    <px:PXSelector runat="server" ID="CstPXSelector2" DataField="UsrTableSelector" AutoRefresh="True" />
    

    【讨论】:

    • Bilal - 非常感谢您发布此信息。它工作得很好。不过,我确实有几个问题...... - 你的项目 #4 不清楚 - 是 'TableDummy' DAC 的 PXUIField 属性吗?如果是这样,我将如何动态更改特定下拉选择的列名? - 此外,由于某种原因,ID、描述字段的顺序颠倒了 - 我可以在查找时轻松更改并保存它,但为什么会先出现描述?无论如何,就是这样。再次非常感谢... -Peter
    • 最后一件事 - 这并不重要,我只是好奇 - 在这种情况下,我将如何使用替代键参数来显示 CD 而不是 ID?
    • @pmfith:我在第 4 步中添加了一个更详细的示例。对于列名,它基于我们在TableDummy 中提供的DisplayName,因此它是一种静态的。我将检查列的顺序并返回答案。
    • 我遇到了一个问题,我不知道为什么。我在选择器上有一个描述字段,我通过 FieldVerifying 事件查询并将描述放置在我页面上的另一个字段中(例如,选择了 InventoryItem.InventoryCD 并查询 InventoryItem.Descr 的 IntenvoryItem DAC - 然后放置字段上的描述)。这通常按预期工作,尽管现在我没有找到“目标值”(目标值是该字段的标签)。它就在那里——它有效——但我不知道错误来自哪里。不知道如何发布更多细节
    猜你喜欢
    • 2021-05-12
    • 2022-01-15
    • 2022-12-15
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2016-02-04
    相关资源
    最近更新 更多