Control : DynamicForm
The DynamicForm control lets you embed one or more forms within another. The control can automatically switch between different forms during runtime, allowing you to create extremely powerful, dynamic user interfaces.
Examples
The following examples are intended to be used with sample code that you can import into your Bungee Builder workspace from the Start Page. Each example is intended to build upon the previous example to provide you with a complete understanding of how to use this control.
Example 1: Simple Embedding of Forms (Ex1_Person)
You can embed a form within another form based on the DynamicForm control's Form property (Adapter tab). The easiest way to implement this is to bind the DynamicForm control to a complex field that you wish to display. Add a form to the class on which the complex field is based, and design the form as you wish it to appear inside the DynamicForm control. Then add a form adapter to the project TypeLib, and assign the form adapter to the custom form's Adapter List property (General tab). Finally, assign the DynamicForm control's Form property (Adapters tab) to use the same form adapter.
In this example, the DynamicForm control is bound to the examplePerson field, which is a complex object based on the Person class. A standard control adapter represents this in the accompanying diagram. The Person class contains two forms—one called detail, another called readOnlyDetail. In order to select which form to use for the examplePerson field, the DynamicForm control is explicitly configured to use a form adapter called Detail_FA. That causes the detail form to display at runtime because the detail form's Adapter List property (General tab) lists the Detail_FA form adapter.
Note Functionally, forms are always view components. However, because the detail and readOnlyDetail forms are encapsulated in the Person class, they are referenced like Model components. Encapsulation of view components within the object model enables you to re-use forms in several powerful ways (such as inheriting a form from a superclass, or re-using a form within various of other forms). A few of these are shown in the subsequent examples.
Click for larger image Run Now
Example 2: Switching Between Forms to Display Different Data Types (Ex2_CurrentObject)
You can use the DynamicForm control to display different types of data by assigning a form for each data type to the same form adapter.
Note Before continuing, simulate the form Ex2_Detail to see this in action. Change the object type in the combo box and see how the interface dynamically changes.
The basic design pattern for this example starts by adding an appropriate form to the class definition of each data type that you want to display. Assign each of these forms to use the same form adapter in their Adapter List property (General tab). Next, bind the DynamicForm control to a polymorphic field—that is, to a field that can become any of the data types that you intend to display. This requires the field to be based on a superclass to all the objects that you intend to display in the DynamicForm. Finally, assign the form adapter to the DynamicForm's Form property (Adapters tab). With this configuration, you can now use some basic application logic to assign different objects to the polymorphic field, causing the DynamicForm control to use the form adapter to select the appropriate form each time the data type in the polymorphic field changes.
The example code shows a simple implementation of this design pattern. The DynamicForm control is bound to a field named currentObject. This field is based on a generic object type named Object, which is a superclass to all object types. There are three other fields—exampleAddress, exampleEmployee and examplePerson—each of which is based on a separate, custom class. In order to supply the example with data at runtime, these three fields have been set to instantiate themselves with some arbitrary default data.
The Combobox control on the form is bound to a field called objectType (for which enumeration has been set with three possible options). When the value of the field changes, the change in value triggers the field's OnChange code to execute. (Double-click the objectType field to view this code.) The OnChange code then assigns the values from one of the three instantiated fields to the currentObject field. This assignment changes not only the values of the currentObject field, but also changes the type of data it contains. This change in type causes the DynamicForm control to switch forms according to its assigned form adapter, Detail_FA. Whichever form in each of the three possible classes (Address, Employee, and Person that is assigned to the Detail_FA form adapter, is then used to display the current object.
Click for larger image Run Now
Example 3: Switching Between two Different Forms for the Same Data Type (Ex3_PersonChangeForm)
The DynamicForm control can display different views of the same class, depending on application state, by switching between two or more forms for that class.
Note Before proceeding, simulate the form Ex3_PersonChangeForm. Use the Combobox to switch between a read-only and an editable view of the same object.
This example closely follows Example 1. A Combobox control is bound to the formType field, on which two enumeration values have been configured. A DynamicForm control is bound the examplePerson field, which is configured to instantiate at runtime with some default data. However, the control does not have a form adapter assigned to its Form property (Adapter tab). Instead, it is configured to use a DynamicForm Adapter called ReadOnly_or_Editable on its Dynamic property (Adapter tab). This DynamicForm Adapter assigns the DynamicForm control to follow the logic in a DynamicFormConnection in order to select which form adapter (and consequently, which form) to use.
The DynamicFormConnection, located in the Person class, uses Model code to assign which form adapter to use. (Double click the DynamicFormConnection object to view its configuration in the Design Editor.) The model code is set to trigger whenever the formType field changes. When triggered, a case condition assigns the correct form adapter according to the value of the formType field.
Note It is important to make sure that you set the Trigger property on the Model header of the Model code, or the change in value will not cause the desired interface change.
The Model-View-Adapter diagram for this shows the two Control Adapter bindings as you would expect. The DynamicForm Adapter is represented by the design view of the DynamicFormConnection to which it links in the Person class.
Click for larger image Run Now
Example 4: Switching Forms According to Multiple Changes in Application State (Ex4_CurrentObjectChangeForm)
The DynamicForm control can trigger off of both the bound object's type and a field that assigns which form adapter the DynamicForm control should use. This example combines elements from the previous two examples to let the end user, at run time, select the object bound to the DynamicForm control as well as which form to use.
Combining these two concepts allows you to make very sophisticated interaction scenarios in your applications.
Note When inspecting the example code, observe that example class Ex4_CurrentObjectChangeForm inherits directly from Ex2_CurrentObject, which provides it several of its fields and other components.
Click for larger image Run Now
Reference
Frequently-used Options
Some of the most commonly used properties that apply to the DynamicForm control are:
- General tab:
- Fade Properties: This allows you to enable a visual fade effect when transitioning from one form to another.
- Slide Properties: Provides you an optional slide-in visual effect when transitioning from one form to another.
- Text on Null: This allows you to display alternate text in the control whenever the field to which it is bound is null. You must enable the field's Nullable property (Behavior tab) for this to work.
- Behavior tab:
- Drag and Drop Zones: The Drag Zone and Drop Zones properties allow you to quickly enable drag-and-drop interactivity. Establish a Drag Zone name, and a corresponding Drop Zones name on one or more controls to enable drag-and-drop. Now end users can move or copy objects from one control to another.
- Technical Note Objects moved or copied by drag-and-drop are actually moved (or copied) between the fields to which the controls are bound. Therefore, you must consider the affect on your application's Model when implementing drag-and-drop.
- Behavior tab:
- Fade on Disable: Causes the embedded form to dim whenever the control's bound field has its State property (Behavior tab) set to disabled.
Supported Types (Control Adapter)
Type |
Summary |
---|---|
You can bind the DynamicForm control to any field within an application object whose type is a complex object (or subclasses Object). You cannot tie the DynamicForm control to a field that is a complex object if that field is a collection (has the Is Collection property set on the field definition). All objects have a special field called this that is a member of the base Object type. You can also connect the DynamicForm control to Object.this. Use care however, when you tie the DynamicForm control to the this field because you can potentially create circular references of forms. For example, suppose you create a form called CustomerForm that references a form adapter named Detail (in its Adapter List property). If you attempt to add a DynamicForm control to CustomerForm that is tied to the Object.this field, and you set the form adapter on that control to be Detail, then at runtime, the form would attempt to create an embedded representation of CustomerForm recursively, forever. If, however, you associate the form adapter with another form on the class, then the DynamicForm control will be able to embed the form even though the form is tied to itself through Object.this. |
Property Adapters
Name |
Summary |
---|---|
The Tooltip property displays the Tooltip as the user moves the mouse within the DynamicForm area. |
|
The Form property is found in the Adapter section of the Property Editor for DynamicForm. You can simply pick any named form adapter. If you set this property, then you don't have to edit the connection adapter, which also allows you to set a form adapter. The DynamicForm control will always check whether you have set that property before searching for the more complex (but powerful) connection adapter found in the same property page. See Dynamic, under Connection Adapters, below, for more information. |
Connection Adapters
Name |
Default |
Summary |
---|---|---|
Dynamic |
DynamicFormAdapter |
Use the Dynamic connection adapter to control what form adapter is used dynamically at runtime (as opposed to just statically choosing a form adapter using the Form property). Using the DynamicFormAdapter, you can cause a form to be displayed at runtime based on application object state, logic computation, etc. |
Connection Adapter: DynamicForm
The DynamicForm connection adapter is always invoked on the application object field to which the DynamicForm is directly connected, and not the parent application object context. If you explicitly set the the Form property to a form adapter, then this connection adapter is not invoked at runtime.
Field Type |
Field Name |
Description |
---|---|---|
formAdapter |
The formAdapter field is used by the DynamicForm control to determine which form to pick at runtime based on the object field to which you tied the DynamicForm. For example, if this field is set to the form adapter called Detail, then when the DynamicForm control invokes this connection adapter and gets the Detail reference, the DynamicForm then requests the application object to which you tied the control to return the form that references the Detail adapter. |
|
object |
Set the object field when you want to set the form adapter that is used at runtime on a particular field without the field’s Object type having to implement this particular connection adapter. For example, suppose you want the parent object of the Person field to choose which form adapter to use to display the Person field. In this case, you would tie the DynamicForm control to the parent’s Object.this field, causing the Object type would to be set to the Person field of the parent object. This ensures that when the DyanamicForm control needs information about which form adapter to use, the control relies on the parent object (the this that is tied to the control directly) but then does the actual form adapter lookup and attachment on the object member of the connection. |
|
objectNullText |
The objectNullText field allows you to set the text you want to display in place of a form when NULL is the object to which the DynamicForm resolves. If the object later becomes valid (non-NULL), then the associated form adapter is used to dynamically query that valid object and return and display the form referenced by the adapter, replacing the objectNull text. |
Function Adapters
Name |
Default |
Summary |
---|---|---|
<not set> |
If you set the Drag Function property, then at runtime when an end-user drags an item into the DynamicForm control, the control calls the Drag Function function adapter on the application object. See the DragDrop API docs for more details on the single argument passed into this function. See also Understanding Drag-and-Drop. |
Function Adapter: DragFunction
Field Type |
Field Name |
Description |
---|---|---|
DragDropData |
dragDropData |
You can use the DynamicForm control’s space to allow drag-and-drop interactions. See DragDrop and Understandaing Drag-and-Drop for more details. |