Microsoft Dynamics AX Support

This blog contains posts by the Microsoft Dynamics AX Support teams Worldwide

AX for Retail 2012 R2: Adding a Custom User Control to the POS

AX for Retail 2012 R2: Adding a Custom User Control to the POS

Rate This
  • Comments 14

In the 2012 R2 release of AX for Retail we have added a very powerful extensibility feature for the POS application:  the ability to add a custom user control to the POS.  This article will show you how to easily create a user control and add it to the POS till layout.  Hopefully it will spur ideas for some creative uses.

Step 1:  Creating the Custom Field

Before you can add your custom user control to the till layout it must first be defined in the Custom Fields window in Headquarters.  This is essentially the same process as custom fields for receipts (AX for Retail 2012 R2: Working with Custom Fields for Receipts) and the till layout (AX for Retail 2012: Working with Custom Fields).  Instead of adding a field to an existing control on the till layout, however, this custom field will be a new control altogether.

in Dynamics AX, open the Custom Fields form (Retail > Setup > POS > Profiles > Custom fields) and create a new field of type Custom control.  The Name field is important to remember as it will be the C# class name of the control.  I used MyControl for this example:

2013-02-26 11_31_40-‪Custom fields‬ (‎‪1‬)‎

Similar to the receipt custom field, the Caption text ID is used for the text of the screen layout designer.  Once again, this ID must match a value in the RetailLanguageText table.  Because there is no form for maintaining this table, it must be modified directly in the AOT.  Open a new developer workspace and navigate to Data Dictionary > Tables > RetailLanguageText.  Right-click and select Open.  Create a new record by populating the languageID, Text and textID fields:  “en-us”, “22002”, and “My Custom Control”.

Step 2:  Adding the Custom Control to the Screen Layout

To add the control to an existing till layout, open the Screen layouts window:  Retail > Setup > POS > Screen layouts.  Click on the Designer button for any screen layout ID:

2013-02-26 11_51_18-‪Screen layouts‬ (‎‪1‬)‎

From the Design mode drop-down button select Main layout to bring up the customization toolbar.  On the Hidden Items tab you should see your custom control.  As you can see in my screenshot I haven’t yet created my string in the RetailLanguageText table:

Once you have your string created correctly, you can then drag your custom control onto the form layout it just like any other item:

Resize your control as necessary and press the OK button to save the layout.  After pushing out the changes (N-1090 or A-1090 job) you should be able to see the control in your POS, even though we haven’t yet done anything programmatically.

Step 3:  Creating the Custom Control

Now comes the development part:  creating the custom control and adding it to the POS.  As long as it implements the interface properly, the control can be included in any POS Service and the layout will find it.  The easiest place for this is… (you guessed it) … the Blank Operation.

Fire up an instance of Visual Studio and open the Services solution.  Navigate to the BlankOperations project;  right-click and select Add > New Item:


Select User Control (you can find it in the Windows Forms sections) and give it a file name.  The file name isn’t really important, but Visual Studio automatically names the class the same as the file name, so save yourself some future confusion and use the same file name as you named your custom field in headquarters:  MyControl.cs:


Your control should automatically open in the designer.  Drag a couple of labels and a button to the control and then to make it stand out, change the Border Style to FixedSingle and the BackColor to a color of your choosing: 


Now that we have made the control visually appealing, we need to add some code to identify it as a POS control.  Right-click anywhere on the control and select “View Code”. 

The first thing to do is add a couple of using statements:

using System.ComponentModel.Composition;
using Microsoft.Dynamics.Retail.Pos.Contracts.UI;

Then implement the IPosCustomControl interface and add two attributes to your class:

    public partial class MyControl : UserControl, IPosCustomControl

If you attempt to build at this point you should get a couple of errors letting you know that you haven’t fully implemented the interface:

The easiest way to take care of this is to right-click on the IPosCustomControl and select Implement Interface > Implement Interface.  This will create two new methods:  TransactionChanged and LoadLayout:

        public void LoadLayout(string layoutId)
            throw new NotImplementedException();

        public void TransactionChanged(Contracts.DataEntity.IPosTransaction transaction)
            throw new NotImplementedException();

LoadLayout() is called when the till layout is loaded and is where you would add initialization code for your control if needed.  You can delete the “throw new NotImplementedException()” line in this method since we will not be using it.

The TransactionChanged() method is the main event handler for the control and is called whenever something changes on the transaction object:  an item is added to the transaction, a payment is received, the transaction is concluded, etc.  As in other POS services and triggers, you have full access to the contents of the current transaction in this method.

Once you have implemented the two methods, you should be able to build and deploy the BlankOperations DLL and launch the POS.  Your control should display in the POS and look something like this:

2013-02-26 14_34_17-Microsoft Dynamics AX for Retail POS


Step 4:  Adding Logic to the Custom Control

Getting the control to display is one thing; getting it to do something is another.  Here are a few ideas we can try out.

First, if we need to work with the transaction and lines on the transaction, a couple more using statements will be handy:

using LSRetailPosis.Transaction;
using LSRetailPosis.Transaction.Line.SaleItem;

Our first line is pretty simple:  just count the actual number of lines on the transaction.  For the second, we will steal the GetTotalQuantity() method the receipts article:

public void TransactionChanged(Contracts.DataEntity.IPosTransaction transaction)
    RetailTransaction retailTransaction = transaction as RetailTransaction;

    label1.Text = string.Format("Sale line(s) count : {0}", retailTransaction == null ? 0 : retailTransaction.SaleItems.Count);
    label2.Text = "Total Quantity: " + GetTotalQuantity(retailTransaction);
private string GetTotalQuantity(RetailTransaction theTransaction)

        decimal qty = 0.0m;
        foreach (SaleLineItem s in theTransaction.SaleItems)
            qty += s.Quantity;
        return qty.ToString();
        return string.Empty;


And then to get the button to do something, just add an event handler:

private void button1_Click(object sender, EventArgs e)
    MessageBox.Show("Do something here...");

Hook it all up and you can see that the control is now functional:


Next Steps:

With some imagination, you can see that this new feature can be quite powerful:

  • Using a timer control, periodically show information to the user (current snow conditions, latest currency exchange rate, company stock price, total sales for the day)
  • Show the elapsed time for the current transaction; change the color of the control if the transaction takes longer than a certain amount of time
  • Provide a call button so the user can notify a shift supervisor that assistance is needed (see note 1)
  • Show a picture of the most recently scanned item (see note 2)
  • Make a pretty clock (see note 3)

Note 1:  Using a button on the control doesn’t really give you much advantage over a Blank Operation aside from the fact that you have more control over the look and feel and it can exist outside of a button grid.

Note 2:  This is a pretty common request.  Note that I said “most recently scanned” and not “currently highlighted” item.  This is because the control doesn’t have access to the transaction grid – only the transaction object.  Since the transaction object doesn’t actually change when focus changes in the grid, the TransactionChanged() method doesn’t fire.  I have raised this as a request for a future version of this feature.

Note 3:  I’ve included a not-so-pretty clock in the attached sample code.


I’m very interested in seeing some of the controls that developers come up with – please drop me a line with some of your examples or if you have any ideas on how to enhance this new functionality.

Leave a Comment
  • Please add 1 and 8 and type the answer here:
  • Post
  • It has been fun following your blog. If you could help in my issue that will be greatful. After Returning the Transaction i need to generate a new receipt, for that i called the receipt from PostReturnTransaction method in TransactionTriggers Project. It is not printing any receipt. I called the same receipt in PreReturnTransaction, the receipt is calling. But i need the Return Transaction receipt only after the payment.

  • Hi Shane,

    We are almost done with the POS setup and the development... we are at UAT stage.. users wanted us to remove the New Customer Link in the Customer Layout... May I know how do we do that??

    Thanks in Advance...

  • HI Shane,

    first many many thanks for the help you did before...

    Now we are trying to customize the POS for Back to School Season to capture the bulk amount or orders from the Schools in South Africa for each pupil in each Grade we are trying to capture the Order from POS against the School Account... in this Process each school will be having 1000's of pupils so when capturing the orders Users does not want to select the Customer Account from each and every transaction because they create order against 1 customer for 1000's of times so.. is there anyway to customer account to be not cleared after the transaction is completed...

    i mean after customer account purchase is done.. I want to clear the transaction but the customer Details...

    Please Help me ASAP..




  • Hi Venu,  unfortunately we don't expose the Customer control at a level that can be customized enough to remove the link altogether.  However, you should be able to create some logic in a PreCustomer trigger to disallow any action from occurring.

    On your second question it seems that what you want to have happen is to have the customer account remembered and then automatically re-added for the next transaction.  I would recommend a Blank Operation button that you could name "Re-use Last Customer" or something similar.  Unfortunately there is no operation to add a customer to a transaction, but all of the logic to do so is in the Customer service (Customer.cs file).  Most of the logic that you could copy into your blank operation resides in the AddCustomerToTransaction() method.

  • Hi Shane

    Is it possible to have a custom control on the main till layout designer that shows whether the product has stock on hand or not? I was thinking a flag?

    A recent enhancement has been raised with a client to allow delivery from another warehouse (not the store you are trading in) when the store has no stock on hand of a particular item. Is this possible to do? Standard R2 Retail unfortunately doesnt extend to this functionality as all sales come from the store you are logged in as, and not another warehouse. I was hoping to customise this functionality by allowing users to select where the stock is being delivered from at time of sale, or at time of customer order.



  • Hi Shane,

    I am taking customer Account Deposit againest an Order in POS. It is creating a Payment type item in POS. Now I want to return the Payment or want to Issue a credit Memo againest it. Please let me know whether it is posible or not. In Simple terms, I want to return payment and issue a credit memo againest it.

  • Is there anyway we can select customer from code behind?

  • Hi Shane,

    I found a way to solve my problem. before Concluding the transaction i.e in PreEndTransaction trigger I am saving the CustomerAccount to the DB table that i have created and when the user initiates the next transaction I will Check CustomerAccount exist in that table for that terminal if it exists then I am adding that Customer to the transaction, It is working 100% fine and POS users are happy.

  • Hi Shane,

    I have products which have a number of colour variants that I regularly use. Since the variants appear in square boxes on the POS, the maximum number of boxes which can be shown on the POS Screen is 35. I am unable to see my other variants on my POS Screen due to the number of variants exceeding 35.

    I have not found any Scroll Bar or Previous Page-Next Page style of buttons to navigate through my variants.

    Are we able to achieve inserting a scroll bar or Previous Page-Next Page style buttons using Custom User Controls? Please assist with any information you may have related to my scenario.

    Thanks in Advance!

  • Mohammed:  This is a known issue and has been fixed.  Please open a support case and have a support engineer get you the hotfix.  It cannot be solved with a customization.

  • Has anyone come across the problem where you have too many reason codes and some drop off because maximum number of buttons has been exceeded?

  • Michelle,

    I just repro'd this by adding a bunch of subcodes on the Discount reason code (by the way, we re-named these back to "infocodes" in R3).  If you have a customer reporting this issue can you open a support case and have it written up as a bug?

    As an alternative, use the input type "Subcode List" instead of "Subcode Buttons" - the subcode list is designed to be used for more input options...

  • I highly appreciate if anyone can help me for following questions.

    Is it possible to setup online real time posting for POS sales transaction? (Update inventory, G/L)

    What is the type of AX license allocated for AX retail Pont of

    sales system (POS) ?

    What is the maximum numbers of Microsoft AX retail Pont of sales

    system (POS) you setup ? Pls mention the numbers of branches also.

    What is the normal leased line band with you are using to

    connect your branches ?

    What is your view to setup MS AX in cloud hosting  ?

  • Hi Shane, would just like to know if there is a way we can force update the total amount due in retailtransaction?

    I have this requirement wherein my client will add additional charge to the total transaction.

    Thank you.

Page 1 of 1 (14 items)