I have a page with a PXTab
control and want to show or hide individual tabs on the page dynamically. How can I control visibility of tabs at runtime?
问题:
回答1:
You can do it in one of the following two ways:
- By setting a VisibleExp property on PXTabItem in ASPX page
- By enabling/disabling AllowSelect property of the view that serves as a DataMember of the grid that is displayed on that tab
Method 1 – VisibleExp In this method, you directly write the conditions under which the tab should be visible in the screen's ASPX code.
<px:PXTabItem Text="Tax Agency Settings" BindingContext="tab"
VisibleExp="DataControls["chkTaxAgency"].Value = 1">
Note that the binding context is important as it specifies which element's DataControls you want to access in the VisibleExp. Also DataControls is collection of values for user interface fields, so you need to specify there IDs of controls (not data access class fields).
However, this method is extremely limited in many ways:
- The condition checking is restricted to controls available in the UI, so it is not possible to condition visibility upon the internal state of the system.
- Sometimes this method will require you to include "fake" data controls into ASPX that will only be checked in VisibleExp, but won't actually be ever seen by the user.
- There seem to be no support for complex conditions including AND/OR.
- Ugly
"
entities instead of normal quotes in the expression – not particularly readable.
Most importantly, if you need to disable the tab for a particular document type, there is no way around hard - coding a constant into a VisibleExp. You would be explicitly writing something like: VisibleExp="DataControls["edDocumentType"].Value != CHK"
Hard-coding is generally considered a very poor development practice. It poses a significant threat to code maintainability: probably the above code is going to break something in the future. For example if you decide to rename the document codes form CHK to CHQ.
In addition to that, this solution is not easily generalized to situations when you suddenly discover the need to hide the tab not only for checks, but also for other document types. This is due to lack of complex conditional expressions mentioned above.
Method 2 – AllowSelect Idea of this method is - if you hide all controls from the tab item, than Acumatica will automatically hide tab with no visible controls.
Lets do an example: assume that you need to hide a tab named Applications depending on the document type selected in SO303000 (Invoices):
The tab that we're interested in has a grid control with a data member set to Adjustments:
<px:PXTabItem Text="Applications" RepaintOnDemand="false">
<Template>
<px:PXGrid ID="detgrid" DataSourceID="ds" SkinID="Details">
<Levels>
<px:PXGridLevel DataMember="Adjustments">
............
</px:PXGridLevel>
</Levels>
</px:PXGrid>
</Template>
</px:PXTabItem>
And not that this tab item has only one control - PXGrid
.
Also note required property here - RepaintOnDemand="false"
. This property indicates whether the control refresh tab items content (and select data) after the item becomes visible. Unfortunately, setting it to false incurs certain performance losses. In particular, the Adjustments view' Select will be called much more frequently.
Currently, the Tab is "smart" in the way that it understands that when its child control (PXGridLevel
) cannot perform a select on its data member; in this case, the tab hides itself from the UI. This is why you can control the visibility of the tab by setting the AllowSelect
property of the cache that corresponds to the Adjustments:
Adjustments.Cache.AllowSelect =
doc.DocType != ARDocType.CashSale
&& doc.DocType != ARDocType.CashReturn;
The above code is written in the ARInvoice_RowSelected
handler of the graph, where ARInvoice
is the primary DAC and the type of the master records of the page. So, every time ARInvoice
is selected, the tab item will become visible or invisible depending on the document type.
This method has its own limitations too:
- You should always remember that it is not enough to disable AllowSelect, you should also enable it when needed. So you need to evaluate this property every time when event is called.
- This method doesn't seem to work without setting the PXTabItem's
RepaintOnDemand
property to false (see above).
Source: http://asiablog.acumatica.com/2016/05/hiding-tab-from-user-interface.html