Improved Studio recognition of Property Values
by
, 13-Aug-2009 at 06:14 AM (3509 Views)
With Visual DataFlex 2008 and above, you no longer need to use meta-tags to declare every change to a property's initial value in a class declaration. Take a look at the following example:
Prior to version 14.1 if you created this cCloseButton class and add it to a view in the Studio's Visual Designer the label doesn’t appear. To make this work, you would need to remember to add the OverrideProperty / InitialValue meta-tags. The problem with this is that:Code:Class cCloseButton is a Button Procedure Construct_Object Set Label to 'Close' End_Procedure End_Class
- You had no idea you had to do this,
- You might know about this but you always forget to do it, and,
- It’s easy to get wrong.
With Visual DataFlex 2008 - 14.1 this is no longer needed.
What Changed and Why?
Prior to version 14.1 the Studio would recognize property values for a class in two ways:
1. When the initial value is set in the property's declaration, for example:
In this example the Studio will recognize that the class cPasswordForm has an additional property and that it's initial value is "False".Code:Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object Property Boolean pbChanged False End_Procedure End_Class
2. When the InitialValue meta-tag is used, for example:
In this example we are modifying the initial value of the Password_State property that is declared in the superclass. Unless you declare the change to the property's default value, using meta-tags, the Studio would model the Password_State property in the new class as having the same initial value it has in the superclass.Code:{OverrideProperty=Password_State InitialValue=True} Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object Set Password_State to True End_Procedure End_Class
In order to set a property value in a class declaration you must execute the Set statement inside the procedure Construct_Object. Strictly speaking, any value that is set by calling a class method is considered a derived value. For example, consider the following class:
In the above example, Password_State is only set to true if the procedure HideCharacters is called. This might never happen during the lifetime of the application, therefore the Set statement cannot be considered as a declaration of the property's initial value.Code:Class cMyForm is a Form Procedure HideCharacters Set Password_State to True End_Procedure End_Class
Easier Modeling
Since Visual DataFlex 2008 – 14.1, the Studio recognizes that Construct_Object is a special type of procedure, like a class constructor, that is always executed whenever an instance of the class is created. Whenever a class property is set within procedure Construct_Object the Studio will now use that value as the property's initial value for the class. For example:
The Studio now recognizes the new initial value for the Password_State property without needing to declare the initial value with meta-tags.Code:Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object Set Password_State to True End_Procedure End_Class
The property's initial value will be represented in the Properties Panel whenever the class, or an object instance of the class is selected in Code Explorer. If it is a visually modeled property, such as Label or Color, then the Visual Designer will render the object applying the correct property value.
It is clearly more convenient to not have to repeat every property setting using meta-tags. These tags also need to be maintained whenever you edit a Set statement. Eliminating the need for meta-tags also eliminates the possibility of synchronization errors, i.e. if you modify a Set statement but forget to change the corresponding tags then the meta-data is out of sync with the source which can cause modeling errors.
Are Meta-tags Still Needed?
Since the Studio will now analyze Set statements inside Construct_Object, is there ever a time you would still need to use the old InitialValue meta-tag? Probably not, but it is worth taking a look at how the Studio analyzes Set statements just in case.
In a class declaration, only set statements inside procedure Construct_Object are applied. Consider the following example:
In this case when an object instance of this class is created the Password_State property will be initialized to true. But the Studio does not try to analyze procedures that are called inside Construct_Object so it does not know about the change to the initial value of Password_State. In order for this class to model properly, you should either move the Set statement inside Construct_Object, or add a declaration of the initial value using the appropriate meta-tags, e.g.Code:Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object Send HideCharacters End_Procedure Procedure HideCharacters Set Password_State to True End_Procedure End_Class
Another common example where set values are not picked up is when you use imported classes (i.e. Import_Class_Protocol). Consider the following example:Code:{OverrideProperty=Password_State InitialValue=True}
Here the values for Password_State and pbChanged must be declared using the appropriate meta-tags.Code:Class cPassword_Mixin is a Mixin Procedure Define_cPassword_Mixin Set Password_State To True Property Boolean pbChanged False End_Procedure End_Class {OverrideProperty=Password_State InitialValue=True} {OverrideProperty=pbChanged InitialValue=False} Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object Send Define_cPassword_Mixin End_Procedure Import_Class_Protocol cPassword_Mixin End_Class
If you are using Procedure Set and Function pairs to wrap a property then you will need to use meta-tags to declare the property's initial value. For example:
What happens when you have conditional code in a constructor? For example:Code:Class cPasswordForm is a Form Procedure Construct_Object Forward Send Construct_Object {Visibility=Private} Property Boolean private_pbSecure False End_Procedure {MethodType=Property InitialValue=False } Procedure Set pbSecure Boolean bValue Set private_pbSecure to bValue // Some special code goes here End_Procedure Function pbSecure Returns Boolean Boolean bValue Get private_pbValue to bValue Function_Return bValue End_Function End_Class
In the above example, the Studio will do its best to update an initial value. It will use the last value inside the If statement (“Hello, there”). If this is not what you want, you can still use InitialValue to set it to the value you want. e.g.Code:Class cMyForm is a Form Procedure Construct_Object Forward Send Construct_Object Set Label to "How are you" If (SomeValue) Begin Set Label to "Hello, there" End End_Procedure End_Class
In other words, the normal cases are handled by the Studio and the InitialValue meta-tag only needs to be used to handle exceptions.Code:{OverrideProperty=Label InitialValue="How are you”}
Whatever method is used to analyze a property's value the InitialValue meta-tag declaration will always have the final say. This means that you can use the InitialValue tag as an override to ultimately control the initial value of a property as it is modeled in the Studio. Note that the meta-tags are used by the Studio. Meta-tags do not actually set the property's value at run time.