Skip to content

Sending Messages Within an Object Neighborhood

DataFlex supports the concept of object neighborhoods. The purpose of this is to make it easier for objects to communicate with each other. Objects within a neighborhood can talk to other objects within the neighborhood by their first name (their simple object name) without needing to worry about where those objects are located.

Object neighborhoods make it easier to manage visual objects within views. In a view, visual controls are often nested inside containers for appearance purposes only. As you design an application, you may decide that it looks better to place several objects within dbGroups and that it then looks better to place those groups within a dbContainer3d. Without object neighborhoods, every time you move these objects around and put them in different containers, you need to change the way those objects are referenced from other objects within the view. This creates the need to generate complex object reference statements and may require code changes every time you move objects around, resulting in code that looks like this:

Get SortOrder of (oSortOrder(oSortParamsGroup(oSetUpContainer ;
    (oTabPageReport(oTabDialog(self)))))) to iOrder

If you decide to move your oSortOrder object somewhere else in the view, you need to start all over.

With neighborhoods, all objects in the view are registered with the view, and all objects within the view are visible to all other objects within the view. The same object placed anywhere within the view is now coded as:

Get SortOrder of oSortOrder to iOrder

In DataFlex, all views and modal panels are defined as public neighborhoods.

Object neighborhoods "flatten" the object structure for all appropriate objects within the neighborhood. For this reason, it is important that all objects within a given neighborhood have unique object names.

Objects can also be explicitly excluded from a neighborhood by setting a special property. This is useful as there are times when you would have special objects that you would not wish to be made public to the rest of the neighborhood. This allows easy access to the objects you want while still writing properly encapsulated applications.

Expected Use of Neighborhoods

All panel objects are defined as being public neighborhoods by default. This includes views and modal dialogs. All objects declared within a public neighborhood will be members of the neighborhood. They can all be accessed from any other member object by their short object name.

All objects contain a property named peNeighborhood. If you wish to make a panel private, you can change the value of peNeighborhood from nhPublic to nhPrivate. Making a panel private will switch off the neighborhood effect within that panel object.

How Neighborhood Object Referencing Works

When an object is created, it will try to register itself with a neighborhood. It does this by checking with its parent object by looking at the parent property peNeighborhood. That property will either define the parent as being a neighborhood object (nhPublic or nhPrivate) or it will tell the object to delegate and check with its parent (nhNo). This process will continue until a neighborhood object is encountered. Once found, that neighborhood object will either be public (nhPublic) or private (nhPrivate). If the object is public, it will register this new object as a member of that neighborhood, allowing all other objects in the neighborhood to access it with its short name. If the object is private, the object is not registered. In either case, the search has ended, and the newly created object is either part of a neighborhood or it is not.

This newly created object will have its own peNeighborhood property setting. This does not affect how it is registered but does determine how its child objects will be registered when those objects are created. In other words, an object's parent determines its membership in a neighborhood.

An object name is found using the following rules:

  1. First, check to see if oName is a child object. If found, use that object.
  2. Check if the object is a public neighborhood. If so, mark as "neighborhood found" and see if the object is in the neighbor list. If found, use that object.
  3. Delegate and see if oName is a child of the parent object. If found, use that object.
  4. If a neighborhood has not yet been found, check if the object is a public or private neighborhood. If so, mark as "neighborhood found." If public, see if the object is in the neighbor list. If found, use that object.
  5. Continue step 3 until there are no more parent objects, in which case issue an "object not found" error.

Only one public neighborhood is ever checked. This means that any object may only belong to one neighborhood. Supporting membership in multiple nested neighborhoods would only create confusion.

Property peNeighborhood

As indicated, all neighborhood behavior is controlled by the peNeighborhood property. All objects support this property. Three modes are supported:

  1. nhPrivate – If an object is private, it means that all descendant objects (all objects within this object) do not support neighborhood referencing. You can think of these descendant objects as not being part of any neighborhood or as being part of a private neighborhood where they just don't like to talk to each other. Non-neighborhood object access methods are still used (check if name exists as a child; if not, delegate to parent and repeat search).

The actual object marked as nhPrivate may be part of a neighborhood, but its descendants are not. An object's neighborhood status is determined by its parent.

Most objects in DataFlex are private. All visual controls (e.g., form, dbForm) and all non-visual objects (e.g., Array, XML objects) are private. In addition, objects created as part of class construction are usually private.

  1. nhPublic – If an object is public, it maintains a list of all of its descendants. When an object name is requested of this object either directly or via object access name delegation, it will search its list to see if the object exists. Views and modal panels are defined as being public. Using this value defines a neighborhood.

  2. nhNo – This mode indicates that this object does not define a neighborhood, either public or private. Instead, it allows its descendants (all objects within this object) to ignore this object and check with its parent to see what its neighborhood status might be. This is the mode that is used by visual containers like groups and container3d. It is the mode that flattens the object structure for visual containers.

We don't expect you will ever have to change this property, with perhaps the one exception of changing a view or modal panel from public to private. Even in this case, we would encourage you to research the need for this change and to see if you can change your application to fully support neighborhoods.

Duplicate Object Names and Neighborhoods

Duplicate object names are allowed within a neighborhood, but only one of those names will be found when the neighborhood list is searched. If you are planning on resolving an object name via a neighborhood, you should avoid using duplicate names. Typically, this will not be a problem. When duplicate names are created within a view, the program rarely needs to find those objects by name – otherwise, you would have assigned the object a unique name. Either you are never sending messages to these objects, or you are creating them dynamically, in which case you should be accessing them by their object handle ID and not their name.

Also, note that a number of classes create objects as part of class construction. You would rarely want to make these objects public, and in fact, they will not be made public. If the object is private, these child objects remain private - this encompasses most objects. Only visual containers are non-private, and even in these cases, they actually are marked private until the end of construct_object. In this case, all the children defined during construction (those objects defined within the class) remain private.