The code is split into three methods for readability and usability. It is always good practice to keep methods concise with a clear purpose.
The first method, SetControlLabel, will accept a FormControl object and a label in order to set its label property. FormControl is the base type for form controls, which is useful, but it does not contain the label property. We could write a method for each type of control, accepting a FormStringControl, FormRealControl, and so on, but this results in a lot of duplicated code.
In order to set the label property, we must check the control's type and then cast it, as shown in the following code:
if (_formControl is FormStringControl)
{
FormStringControl stringCtrl = _formControl;
stringCtrl.label(_label);
}
The other option we have, which seems more elegant, is to use code similar to the following:
switch (_formControl.type())
{
case FormControlType::String:
FormStringControl stringCtrl = _formControl;
stringCtrl.label(_label);
break;
// etc.
}
This is not documented officially, so this wasn't used here. The ideal method would be an interface where we would write something like the following:
if (_formControl is FormControlLabelI)
{
FormControlLabelI labelCtrl = _formControl;
labelCtrl.label(_label);
}
Sadly, there is no such interface, but should one be made, it would be a simple process to change our code in order to use it. This is one of the many reasons why interfaces are so useful and why we should use them more and more in our code.
The second method, ProcessControl, has the task of accepting a FormControl object and determining if the label should be changed and what the label should be.
We might evolve this so that we have a setup table that contains a list of fields and the desired label. The following code should be used to get the field name so that this new label can be looked up:
RefFieldName fieldName = _control.fieldBinding().fieldName();
In our case, we will just use the field name to add it to the label, in order to show that the concept works.
The final ProcessGridControl method shows a standard pattern of iterating through a container control in order to access the controls within it. Groups and grids are both container controls, and the pattern in this method can be used with both types of container control.
When this technique is used properly, it can prove very useful. Some examples are as follows:
- Custom fields where the purpose is not known at design time.
- To show rolling balances where the months are relative to today.
- On some setup forms where the fields are reused. An example is a business event's endpoints where the URL field changes based on endpoint type.
This should be done to change labels for standard elements as this can lead to problems with supporting users, as well as form load time.