Code highlighting

Saturday, October 20, 2007

List panels in Dynaics AX - a short description of SysListPanel class

SysListPanel class – what is it?

Whenever a user needs to select a number of values from a certain list, so that the selected list gets processed and saved, a list panel can be used. Another use of this type of control is when you are assigning certain properties/options to a specific object.

A good example is the “Administration\Users” form, where each user is assigned to one or more user groups, giving him certain access to DAX functionality.

Here is how it looks:


SysListPanel is the basic class for a large hierarchy of classes showing different list panels throughout the application.

The hierarchy tree for this class is shown below (DAX 4.0 SP2):

One important thing you need to understand when working with list panels – the class is not enough. :) When there is a class, there is a form, containing the list panel and using this class. But, of course, the class is responsible for most of the things happening when a user works with list panels.

SysListPanel or SysListPanelSet – which class to use?

When I consider, what class to extend when creating a list panel on a form, I start off by figuring out how the selected data is going to be stored. If the data selection is supposed to be reflected in the database (for example, when we add the user to a user group, a record is created in UserGroupList table), then extending from SysListPanel should be your choice in most cases.

SysListPanelSet is already an extension of the SysListPanel class, and has one extra variable declaration – inSet variable of type SET. This is the entity that is going to store the values a user selects in the list panel. They can, when selected, be used for further processing.

The SysListPanelSet_TableBrowser class, used in the DEV_SysTableBrowser project (http://www.axaptapedia.com/DEV_SysTableBrowser) is an example, using this set to create the selected controls in the browser.

You should also notice from the SysListPanel hierarchy tree, that there are a lot of classes already available in the application, so it is wise to re-use one of the existing classes, if it matches your requirements or extend from one of them and not from the base class.

Again, the SysListPanelSet_TableBrowser class is an example, as it is extending from the SysListPanelSet_Fields class. It uses the functionality of this class to get the data about table fields, extending them with information about display methods and interaction with the browser form.

Creating a list panel – what methods need to be implemented?

Let’s say the SysListPanelSet_TableBrowser class does not exist yet, and we are just planning to create it, along with the form.

Creating the form is the easy part. There are not many requirements that have to be fulfilled here.

First of all, of course, you need to have a variable to reference your listPanel class. Put it in the classDeclaration of the form, so that it is visible in all form methods. And after that all that is left to do is to create an object of your listPanel class, and the class will do the rest of the work.

Here is what needs to be done:
  1. In the init() method of the form, you need to initialize the listPanel class, specifying, that it is this form you want the list panel to be on, the group that the list panel is going to be in on the form, and any other relevant parameters (for example, when using SysListPanelSet, you usually pass the current state of the values (inSet) as well.
  2. Most convenient way to accomplish this is by creating a static method with the needed list of parameters, and call this method from the init() method of the form. Usually, this method is named newForm.
  3. The SysListPanel class contains a lot of parm* methods, that you can use to modify the behavior of the list panel. The SysListPanelSet adds another method to that list, allowing to set the current set of selected values (parmInSet). You can see how these methods are used in Classes\SysListPanelSet_Fields_TableBrowser\newForm() method.
  4. After basic initialization you have to call the build method. The build method of SysListPanel class is responsible for actually adding all the needed controls to the specified form. Depending on the parameters that you set before calling this method, the list panel will/won’t add the “Add All”/”Remove All” buttons, the “Up” and “Down” buttons, will set the needed number of columns shown in the panels, etc. You can override any of the methods, adding additional functionality (see \Classes\SysListPanelSet_TableBrowser \build() method) or even completely rewrite the code of the basic method (this is not recommended, of course). Notice, that the build method should be called BEFORE super() in the form’s init() method, because FormBuild*Control classes are used to add controls to the form.
  5. After build method is executed, all FormBuild*Controls are initialized. You need to call the init method then, so that all Form*Control variables are initialized. This method should be called AFTER the super() call in the form init method, as Form*Controls don’t exist until super() is called.
  6. The last thing you have to do is call the fill method of your new class, so that the list panel is filled with needed data. Let’s talk about this method in a little more detail below.

The Classes\SysListPanel\fill() method, basically, consists of 4 parts:

  1. getData method is called. This is the method that gathers the data for the left and right part of the list panel. This is an abstract method, and it has to be implemented in the extending class. It returns a container with all the information for the list panel. It is different from class to class and depends on the data being shown in the list panel.
  2. Both parts of the list panel are cleared and list panel columns are created (the first time).
  3. fillView method is called for both parts of the list panel. These methods use the data generated in step 1.
  4. Buttons are enabled depending on the data in both list panel parts. For example, if there are no items selected (left part of the list panel), than the "Remove" and "RemoveAll" buttons are disabled.

The rest of the methods on SysListPanel class are for handling events that occur from user interaction.

The class is the handler of these events in most cases, controlMethodOverloadObject method is used to specify that when the list panel is built.

I guess, the only two methods left that are worth mentioning are the abstract methods addData and removeData. Both of these have to be implemented in the child class, providing the logic for adding and removing items from the left part of the list panel. For example, for SysListPanelSet class the implementation is very simple, just adding or removing the item from the inSet object. For classes extending directly from SysListPanel these methods are where the main logic is located, adding or removing records from the database. In most cases, these methods simply call a server method that does all the needed actions (Remember the rule of thumb – place database logic as close to the database layer as possible).

That is pretty much all you need to know to use and create list panels in Dynamics AX.

Conclusion

Of course, this is not a full description, and much can be added to the information posted here.

If you have any additions, corrections or questions, feel free to post them as comments.

See also

\Forms\Tutorial_SysListPanel

Friday, September 14, 2007

DEV_SysTableBrowser version 2.0 is out!

I have been asked by a number of my blog readers to move this tool to Dynamics AX 3.0, so here is the updated version of this tool. Now it works on both DAX 3.0 and 4.0 (tested on 3.0 SP5 KR2 and 4.0 SP1 and SP2).

Also, I added a couple of things I considered useful to this new release:
- The user field select dialog option has now, by default, all the non-system fields selected, so that users don’t get surprised when no fields are selected. I agree – it does look strange :)
- Now it’s possible to select display methods along with table fields in the user field select dialog. This feature was already working with FieldGroups, so I decided it could be a nice add-on to the User Field List option
- I also fixed a couple of old (and new, brought to us by 4.0 SP2) bugs that existed in the tool
- After reading some of the last posts on AxForum, I decided to add the ability of browsing temporary tables into my project as well, so that others may use them if they want :) (this will also include browsing temp tables data shown in forms from Tabax when the next version comes out)
- Now you can also use the browser for debugging purposes, launching it from code (this works for temp tables as well). Just write:

SysTableBrowser::browseTable(table.TableId, table);

where table is a cursor (second parameter can be omitted for non-temp tables). In this case the browser will open and code execution will stop until you close the browser (if not in a transaction). Third parameter controls if code execution should be stopped.

- There are two variables in method new of class SysTableBrowser
saveQueryRun = true; // Enables/Disables queryRun saving when new options are specified
savePosition = true; // Enables/Disables cursor position saving when new options are specified

The options allow to save the user filters and cursor position when changing setup options.
Both operations could result in performance problems on large tables.
If that happens (or you just don't need them), just turn them to false. :)

The download link is: DOWNLOAD

See extended installation instructions and tool description on: HOMEPAGE

What was a little disappointing is that a number of bugs I wrote about earlier were not fixed since SP1. Here are the 2 I mentioned before, again:
- UPDATE_RECORDSET command, when used in the table browser, crashes DAX.
- The left top edge position (the coordinates) of the table browser gets reset when any of the options are changed. I fixed this by specifying 0 instead of -1 for the leftMode and topMode properties of the design. So when you download this tool, the browser will stay in one place, which is nice ;)

Also, 1 new bug I found is for the Russian localization team.
- Changing the view (in the Unmodified version of the browser was causing the full table list to open, prompting the user for a selection of the table). This is caused by a small validation in the SysTableBrowser::main() method. SysSetupFormRun is supposed to be the classId of the calling object. And it is not, because some system wide changes were made to the SysSetupFormRun::construct() method. Anyway, I fixed this small bug as well.

OK. That’s all about the tool and the bugs. I have also been asked by a couple of my readers to write a tutorial on using the SysListPanel class.

That’s exactly what I am going to write about in my next blog entry. After all, there is a new class extending from the SysListPanel class in the DEV_SysTableBrowser project.

Monday, September 03, 2007

DEV_CreateNewProject tool version 2.0.0

Hello, everyone.

I finally got down to moving the latest version of this tool to Dynamics AX 4.0.
Now there is only one project for both versions (3.0 and 4.0)

If you haven't seen this project before, you are welcome to visit the homepage, which contains a description of the features, screenshots, installation instructions and more.

The download link with the new project is:
DEV_CreateNewProject version 2.0.0

Important:
The project was renamed to fit the naming conventions of Dynamics AX. The new name is DEV_CreateNewProject.

(If you want, you can remove the previous version (AxCreateNewProject)).
Leaving them in your application WILL NOT have unwanted effects on your system


Also, I would like to share some knowledge that came upon me today with you.
This might not seem strange to you, but it sure was a surprise for me.
While testing the new version in Dynamics AX 4.0 SP2, I noticed that the form size and position are not saved when I press OK in it.
I dug deeper into system classes and found one extra condition that was added before any data for the form is saved.

The extra condition is:
The AllowUserSetup property on form design must be Restricted or Yes.

So you should keep this in mind when developing forms in the future.

Well, have a great day, all of you.
And do try out the new DEV_CreateNewProject version.

Wednesday, August 22, 2007

tutorial_Form_Dynalink (a small tutorial on dynalinks)

Today I was asked the following question:

"In dynamics we have a Form Named "Form1" I created a button on it "Button1".
It will manage all the records related to the key in main form. There is dyna link created between the datasources. Only records of the currently selected main Key field will be shown. I need the selected KeyField value on the other form. How can I get it?"


So I wrote a small project to show the different possibilities.
In the project you will find 2 forms, 2 tables and a menuItem connecting the two forms.
3 ways of getting the current dynalink value are shown.

Here is a link to the xpo with the project:
download

Here is a screenshot of the result:



Forgot to give some explanations as well: :)
Basically, all the 3 form methods showing different ways of getting the dynalink value are called from the linkActive method in the second (slave) form.
This method is activated by the system every time a record in the parent form is changed, which allows for dynalinks to work. Great method :)

Monday, July 16, 2007

Fetching Data experiment (CacheLookup property)

Playing around with certain table properties at work, trying to improve performance, I decided to post some results today.

The original job was taken from the Dynamics AX Development training materials (III and IV), which, taking the opportunity, I would like to recommend for reading. Especially I enjoyed chapters dealing with performance issues (a topic that is very interesting to me :))

Well, they write about measuring caching there, which they, actually, shouldn't do, because the job they provided won't work in DAX 4.0 (the counters will be zero) (I guess it was simply copy-pasted from DAX 3.0 training materials - you should never use copy-paste, especially with code :) - trust me, been there many times)

Anyhow, I modified the job a little bit to make my research a little easier.
Here are the results I have received for SalesTable:


Basically, running the job may help you decide, what is the best CacheLookup property value for a given table. 
But first priority is reading about it in tutorials or the Inside Dynamics AX book (basically, it's almost the same information on this topic)

You can do some R&D yourself by downloading the job: download
Have fun!

Also visit the homepage