在Acumatica中动态更改PXSelector

时间:2016-05-05 15:02:58

标签: c# acumatica

我有以下用例:

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

e.g:

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

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

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

我知道我必须使用自定义选择器属性,但有关如何执行此操作的详细信息并不清楚。

1 个答案:

答案 0 :(得分:6)

正如您所说,您需要实现一个继承自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,具体取决于您的下拉菜单,您需要设置您将在选择器中使用的字段的可见性。< / p>

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

[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" />