Sending an enum parameter to a form allows a form to be re-used for several different purposes. Developers can send parameters to forms in D365 F&O to control what data and controls are shown on the form. This creates a better experience for the user. Allowing them to focus on only what is needed for the specific purpose.
Ways To Send Parameters to Forms
There are a few different ways of sending in data to a form. However, all of them use a global class named Args. The Args class contains several properties that can be populated with information. This information can then be read from inside the form you are calling.
There are two main ways that the Args class object is populated.
- The Args class can be populated directly using x++ code.
- Or it can be set by the system by a developer setting properties on a Menu Item.
In the previous article, I showed you how to create a Menu Item, and add it to a Menu.
In this article we are going to cover the second way of populating the Args class object. Which is to use a Menu Item. I will then follow up with an additional article that explains how to set the Args object through X++ code.
Key Properties On The Menu Item
Menu Items provide a very straight forward way for developers to send enum parameters to Forms in D365 F&O. There are several properties on the Menu Items whose values will automatically get copied into an instance of the Args class object, and then sent into the calling form.
The two key properties that developers can set on a Menu Item are Parameters, and Enum Parameter. In this article I will focus on how to use the ‘Enum Parameter’ property. Which is used in conjunction with the ‘Enum Type Parameter’ property.
Enum Type Parameter and Enum Parameter
Enum Type Parameter and Enum Parameter: These two properties are used together. A developer can set an enum type in the ‘Enum Type Parameter‘ property. And then set the specific enum value in ‘Enum Parameter‘ property. For example, perhaps there is an enum named ‘FormMode’ that has two values: ‘Full Operation’ and ‘Read Only’. The Enum Type Parameter would be set to ‘FormMode’. And the Enum Parameter property would be set to either ‘Full Operation’ or ‘Read Only’. The calling form could then read the value of the enum, and behave differently based on that value.
These values get copied to the ParmEnumType and ParmEnum properties on the Args class.
In my opinion, it is often preferred to use the Enum Type Parameter and Enum Parameter , over the ‘ Parameters ‘ property. These have a set list of enum values. A developer can then make sure they handle each possible value within the calling form. Whereas the Parameters property can pass in any string. Therefore, the calling problem may not know how to handle all of the string values it could be passed. And if there is a typo in the x++ code, this will not be caught at compile time.
Send Enum Parameters To Form Example
In this article, I will show you an example of how to send enum parameters to forms in D365. For this example, we will use the Enum Parameter and Enum Type Parameter Menu Item properties.
To begin, create a new solution and project in Visual Studio.
Then, either create a Menu Item or duplicate an existing one.
If you create a new one, set the Object Type to Form. Then set the Object to the name of the form you would like to call. In my case, I set the Object to ‘rsmVehicleServiceWorkbench’ to open a custom form I have.
For this example, duplicate this Menu Item, and rename it rsmVehicleServiceWorkbenchFullOperation.
Next, create a new enum, with the values you would like to read within your form. In my example, I created an enaum named ‘TutorialVehicleServiceWorkbenchMode’. I then added to enum values: ‘FullOperation’ and ‘ReadOnly’.
Now that you have an enum, you can set the ‘Enum Type Parameter‘ and ‘Enum Parameter‘ on the Menu Item.
Set the Enum Type Parameter property to ‘TutorialVehicleServiceWorkbenchMode‘. This indicates which enum we wish to use.
Set the Enum Parameter to ‘FullOperation‘. This specifies which value in the enum we wish to pass to the form. This allows us to create multiple menu items, each with a different enum value sent to the form.
Override The Init Method On The Form
In almost every case where you send parameters to forms in D365, you should override the Init method on the calling form. The Init method is a method that is called by base system code when the form is first open. It is responsible for initializing all of the form components. This is the logical and expected place for us to read in the passed in parameters. Then use those parameters to control the behaviour of the form.
The same steps I describe here will work on whatever form you use. I will just use the name of the form I am using in this example.
Add the form rsmVehicleServiceWorkbench to your project. Open the rsmVehicleServiceWorkbench form in the form designer in Visual Studio by double clicking on it. Expand the main form node, and select the ‘Methods‘ node underneath it.
Right click the Methods node, and select Override>Init.
If you or another developer has already overridden the ‘Init’ method it will not show up in this drop-down. In that case, expand the ‘Methods’ node and look for the ‘Init’ method. Right click on the form node and select ‘View Code’ to open the code editor for this form.
Add Code To The Init Method
After overriding the Init method, we need to add code to the Init method. In the code editor window, locate the Init method. If you just created it for the first time it will look like this.
public void init()
{
super();
}
The call to super() runs all of the base system code. This code creates all of the components of the form. Because we will want to interact with the components on the form, it is necessary that we put our code after the call to the super() method.
Add the following code to the init method, so that is looks like this.
public void initEnumParameter()
{
super();
if (element.args())
{
//Handle the scenario where the args sends in a TutorialVehicleServiceWorkbenchMode enum.
//Use the passed in enum to control whether you can edit the form or not.
if (element.args().parmEnumType() == enumNum(TutorialVehicleServiceWorkbenchMode))
{
mode = element.args().parmEnum();
element.changeFormBasedOnMode();
}
}
}
Also, add a variable named ‘mode’. Add it above the init method, but still inside the form class. It should be of enum type ‘TutorialVehicleServiceWorkbenchMode’.
TutorialVehicleServiceWorkbenchMode mode;
Explaining The Code
Let’s discuss what each piece does. You can then make changes based on what is in your form.
if (element.args()) : The first thing we do is we check to see if the form has an instantiated Args class. The way we do that is to check if the args() method on the element object, which refers to the form, returns a value. If it does, we can proceed. Without this check, if we try to call methods on the Args object, we will get a null reference exception at run time.
if (element.args().parmEnumType() == enumNum(TutorialVehicleServiceWorkbenchMode)):
The value we entered into the Menu Item ‘Enum Type Parameter’ property is copied by the system into the Args class object. We then can read that value out, by calling element.args().parmEnumType(). Then, we compare that value to see if it is the enum we wish to handle in this condition. In this case ‘TutorialVehicleServiceWorkbenchMode‘. The global method ‘enumnum’ returns for us a unique identifier for this enum. We might have multiple conditions in this Init method, checking for different enum types to be passed in.
Now that we have verified that the enum type is TutorialVehicleServiceWorkbenchMode, we can check the value.
mode = element.args().parmEnum();
The above line of code will get the particular enum value out of the ‘Enum Parameter’ property. It then stores it into a variable named ‘mode’.
Adding A Form Method
Now that we have retrieved the value out of the args, we want to take action. Instead of putting the needed code directly into this method, I created a new form method, and put the code in there. Please add this method to the form’s code.
public void changeFormBasedOnMode()
{
switch (mode)
{
case TutorialVehicleServiceWorkbenchMode::FullOperation:
rsmVehicle_ds.allowEdit(true);
rsmVehicle_ds.allowDelete(true);
rsmVehicle_ds.allowCreate(true);
FormButtonGroup.enabled(true);
break;
//Do not allow editing, deleting, or creation on the datasource in 'ReadOnly' mode.
case TutorialVehicleServiceWorkbenchMode::ReadOnly:
rsmVehicle_ds.allowEdit(false);
rsmVehicle_ds.allowDelete(false);
rsmVehicle_ds.allowCreate(false);
FormButtonGroup.enabled(false);
break;
}
}
Inside this method, I check the value of my variable ‘mode’. If mode is set to ‘FullOperation’, the code will make sure that a user can create, edit, and delete records in the datasource. If however, the menu item passed in the enum value ‘ReadOnly’, the system would disable the datasource, and disable the button group on this form.
Controlling The Form
In my example, I referred to the Data source that is on this form. The name of the Data Source is ‘rsmVehicle’.
In order to refer to a Data source in x++, you need to add ‘_ds’ on to the end of the name of the Data Source. <Data source name>_ds. So in my case, I used ‘rsmVehicle_ds’. I then called the methods, allowEdit, allowDelete, and allowCreate, and passed in false to each one of them. This effectively puts the form into a read-only mode.
Additionally, I have a button group on my form that contains all of the buttons. The name of the button group control is ‘FormButtonGroup’. I set the Auto-Declaration property on that button group to ‘Yes’ so that I could refer to this name in x++ code.
Then, I called FormButtonGroup.enabled(false) to disable all of the buttons in this button group.
Again, you can take whatever action you would like. This is just what I did for this example.
The Args Record Property
There are a few additional properties on the Args class that can be used to send parameters to forms in D365. However these are properties that do NOT exist on the Menu Item. These properties are set differently.
Record: The record property on the Args class stores an entire table buffer. This property is not set when calling a Menu Item from a Menu. However, if you have a Menu Item Button on a form, you can set the ‘DataSource’ property on this Menu Item Button. And then the system will automatically use the selected record from the current form, and put it into the Args.Record property, and send it to the calling form.
This is very useful. As often times you would like the form you are opening to understand the context from the calling form. And if the calling form uses the same datasource, the form will automatically filter itself to only show the passed in record. I will cover this in a separate article.
Conclusion
In conclusion, a developer can send parameters to forms in D365. One way they do this is by setting properties on a menu item. The data and form elements are then controlled, based on this input. This is very useful. Developers do not have to create two or more forms that are very similar. They can create a single form, and then control how the form works based on information sent into the form.
Leave a Reply