View RSS Feed

Development Team Blog

Improved Studio recognition of Property Values

Rate this Entry
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:
Code:
Class cCloseButton is a Button
    Procedure Construct_Object
        Set Label to 'Close'
    End_Procedure
End_Class
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:

  1. You had no idea you had to do this,
  2. You might know about this but you always forget to do it, and,
  3. 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:
Code:
Class cPasswordForm is a Form
    Procedure Construct_Object
        Forward Send Construct_Object
        Property Boolean pbChanged False
    End_Procedure
End_Class
In this example the Studio will recognize that the class cPasswordForm has an additional property and that it's initial value is "False".

2. When the InitialValue meta-tag is used, for example:
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 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.

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:
Code:
Class cMyForm is a Form
    Procedure HideCharacters
        Set Password_State to True
    End_Procedure
End_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.

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:
Code:
Class cPasswordForm is a Form
    Procedure Construct_Object
        Forward Send Construct_Object
        Set Password_State to True
    End_Procedure
End_Class
The Studio now recognizes the new initial value for the Password_State property without needing to declare the initial value with meta-tags.

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:
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
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:
{OverrideProperty=Password_State InitialValue=True}
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:
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
Here the values for Password_State and pbChanged must be declared using the appropriate meta-tags.

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:
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
What happens when you have conditional code in a constructor? For example:
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 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:
{OverrideProperty=Label InitialValue="How are you”}
In other words, the normal cases are handled by the Studio and the InitialValue meta-tag only needs to be used to handle exceptions.

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.

Comments