Code highlighting

Showing posts with label control. Show all posts
Showing posts with label control. Show all posts

Saturday, April 15, 2017

Development tutorial link: Extending the Warehouse management functionality after application seal

Background


At the Dynamics 365 for Operations Technical Conference earlier this year, Microsoft announced its plans around overlayering going forward. If you have not heard it yet, here's the tweet I posted on it:


 AppSuite will be "soft sealed" in Fall 2017 release and "hard sealed" in Spring 2018 - move to use  in your solutions

However the application SYS code still has a number of areas which are difficult to impossible to customize without overlayering. One of such areas is the Warehouse management area.

Improvements

In the SCM team we have been focusing on improving our Extensibility story in the application, which also includes the above mentioned warehousing area.

Below are a few posts Michael posted recently describing some of the changes we have done in the Warehouse management area, which are now available as part of Microsoft Dynamics for Operations Spring 2017 preview.
This should allow customizing the warehousing functionality to a large degree without the need to overlayer the code.

Extending WHS – Adding a new flow
Extending WHS – Adding a new control type
Extending WHS – Changing behavior of existing control types
Extending WHS – Adding a new custom work type
Extending WHS – Adding a new location directive strategy

Please look through these changes and let us know if YOUR functional enhancements are still impossible, so we can get them addressed.

Thanks

Monday, May 11, 2015

Tutorial: Caching display methods

Overview

Caching is an important part of the Microsoft Dynamics AX application. It allows us to significantly speed up certain processes by avoiding redundant round trips to the server and the database. Display/Edit methods are a good example of where caching is helpful, as it significantly increases the overall responsiveness of a form.
In AX 2012 R3 there are a number of ways you can specify that a display method needs to be cached. Below is a list, as well as a brief description and an xpo with a tutorial form to show the various options.
  • Invoke cacheAddMethod(MethodName) in the init() method of the data source
This is the only option that was available in older versions of Dynamics AX.
All cached data methods are calculated and cached in executeQuery of the data source they belong to. That is why it is important to call the above method in the init() of the data source, once the data source is initialized, but the data hasn't been retrieved yet. The optional second parameter controls whether or not the display method value should be refreshed when data is written to DB
  • Add the SysClientCacheDataMethodAttribute attribute on the display method
Now that attributes are available, caching a display method is as easy as adding an attribute on the method. It has an optional parameter same as the above method. Note, that marking a display method with this attribute will mean that it is cached on all forms the method is used on. So make sure that is what you want to happen before adding it.
  • Set the “Cache data method” property on the display method form control to Yes
This is, again, a new capability in the latest version of AX, that is pretty much identical to calling the cacheAddMethod, just much easier.
  • Set the “Cache data method” property on the display method form control to Auto, where the data source is read-only
Now, this is something that is done automatically by the kernel. If the data source which the display method belongs too is read-only, and Cache data method property on the corresponding control is set to Auto, the kernel will cache this method. This is smart, as the value can’t really change. You can still change the property to No, if there’s a reason why you want the display method not to be cached.

Additional info

On top of the above, I would also like to mention a few other things.

  • There are 2 kernel-defined methods, called titleFields and parentTitleFields, which are always being cached automatically by the kernel. The titleFields method corresponds to the 2 Title Fields that you can set on the table level. Then, if you have this table as your TitleDatasource on the form design, the 2 fields selected will be shown in the caption of the form. parentTitleFields is very similar, only it displays the title fields of the parent data source table, which is relevant in a header-lines (dynalinked datasources) kind of scenario. As a fallback, it shows the titleFields.
  • There are methods for managing the cached methods, one of them being cacheCalculateMethod, which asks the server to re-calculate the method value and update the cache for the current record. Note that it will only take effect if the method has previously been cached. In the tutorial project I am using this method in the form method runHack to refresh the value of 2 of the display methods. 

Example

You can download the xpo project with the tutorial from my OneDrive.
Upon opening the form in the project, some data will be pulled into the form. More specifically, the first 3 items/customers/vendors/sites/warehouses. For each of them a display method is present, and one of the above approaches is used to cache it.

Step 1



None of the display methods are cached. As you can see, nothing extra was done in executeQuery of the main data source, but itemName was cached for all 3 records for the read-only data source, as the control has "Cache data method" property set to Auto. This happens even though the tab page is not the active one, so it wasn't really yet necessary to calculate these values. Maybe the user won't even navigate to that tab page. You should consider this carefully when designing a form, and always aim at increasing the overall responsiveness of a form by only executing the appropriate display methods.

Step 2 and 3



inventSiteName and vendName were cached (through one of the options above). As you can see, now their values are calculated once for each of the records shown. InventLocationName and custName are still not cached.
Clicking on Refresh result button will show any extra calls to the display methods since the form started. As you’ll quickly notice, the non-cached methods are being called every time something hints at covering up the value of the control, or rather every time AX thinks it needs to recalculate the value, which is VERY OFTEN. That should make it pretty clear how useful caching is for display methods.

Step 4



Now inventLocationName was also cached, and the only method that is remaining and not cached is custName. You can see how more and more methods are executed in one batch on the server as part of the executeQuery method on the data source.

Step 5



As the last step, I have added 2 standalone controls that show the Title fields of the main data source table, and started logging the time method caption is invoked. As I have written above, titleFields and parentTitleFields are cached automatically, but you can't really see it, as it is not possible to override it. caption is the closest you can get to it, so I figured it's worth showing that. You can see the method is evaluated right after all data source queries have executed (as it relies on the currently selected record). It is evaluated first time based on the selected data source record, and then again when focus actually goes to the grid, so that the first record is explicitly selected. It will be invoked again whenever the active record changes. Note that unlike custName method, it does not get constantly refreshed.

Play around with the form and let me know if you have any questions or comments.
Thanks

Friday, December 19, 2014

Tutorial: Auto-Complete functionality on form controls


I guess all of you are familiar with the Auto-Complete feature present in Dynamics AX. Whenever you type in a repeated value in a control on AX forms, an automatic suggestion pops up next to the entered characters and the user can choose to accept the suggestion (for example, by tabbing out of the control).
There are methods on the form (specifically, the FormRun class) that provide you with a more tight control over the auto-completion list available to the user, and this blog post will describe the behavior of these methods, as there are a few not obvious things there.

Method signature Method behavior description
getAutoCompleteString(int _elementIndex) Retrieve the auto-complete string saved under the specified index in the auto-completion list of the form.
The indexing is not control-specific, and is not very efficient at keeping the number of values in the list low, so you will see values from multiple controls here.

The method returns a container containing 2 values:
- the auto-completion string value
- the index of this string in the auto-completion list
getAutoCompleteString(int _startIndex, FormControl _control, str _searchStr) Retrieve the auto-complete string for the specified control, finding the first one in the list starting from the specified startIndex + 1.

If _searchStr is also specified, it will find the first matching entry in the list with index > startIndex. This is the closest behavior to what happens when a user types in a certain character in the entry control on the form and the kernel needs to search and populate the auto-complete value for it.

Note: There’s a small bug in this function, where it does not return the full string value for longer texts. A workaround is to use the above “overload” and retrieve the full value by index.
setAutoCompleteString(string _string, anytype _control) The first argument is clear, and that is the auto-completion string to add to the list of suggestions.

The second argument is presented as _control, but can accept either an instance of a FormControl, or an integer value of the list item index to set.

If the _string already exists in the auto-completion list for this control, nothing will happen. If it does not exist, a new item will be added to the list (number of items cannot exceed 300) with the next available index.
setAutoCompleteString(string _string, anytype _index) The auto-completion list item at index _index will be updated in the list with the specified _string value.

This method “overload” basically allows you to override a particular value in the list with a new value.
delAutoCompleteString() Deletes all auto-completion items from the list, regardless of which control they are bound to, if any.
delAutoCompleteString(anytype _index) Deletes the item with the specified index from the auto-completion list.
delAutoCompleteString(anytype _control) Deletes all auto-completion items for the specified control from the list.

When a value in one of the controls on the form is modified, this value is also automatically added to the auto-completion list. With the above methods, however, you can control, if this value should actually stay there, or be immediately removed.
This way you can, for example, restrict the user to only be provided with auto-completion hints from a certain list (similar to IntelliSense).

I created a simple form to demonstrate all the above methods in action.

Tutorial auto-complete capabilities form
Tutorial form to demo auto-completion capabilities

You can download the form from my OneDrive.


Apart from the above methods, there is also a global setting which allows you to control auto-completion list availability for a particular user. This is control on the User options screen, as highlighted in the below image:

Autocomplete in User options
User options form


If this check box is not set, auto-completion suggestions will not be shown to the user when entering data on forms, even though the auto-completion list is still maintained behind the scenes.