Enabling Attribute Linking

Introduction

In SAS/AF software, attributes can facilitate communication between components. You can enable one component to automatically update the value of one of its attributes when the value of another component attribute is changed. In the SAS Component Object Model, this interaction is called “attribute linking,” and you can implement it without any programming.
As a component developer, you can decide whether the components you design support attribute linking. You can use the Class Editor to add attribute linking capabilities.
  • To enable an attribute to receive its value via an attribute link, simply set the attribute's Linkable metadata item to “Yes.”
  • To enable an attribute to function as a source attribute (that is, the attribute to which you link), you must set the attribute's SendEvent metadata item to “Yes.”
Most attributes on SAS classes are linkable.

What Happens When Attributes Are Linked

Introduction

During build time, you can use the Properties window to add attribute links. When you add an attribute link, the component's _addLink method runs. The _addLink method specifies the attribute to which you want to link, the object you are linking from, and the source attribute for the link.
Similarly, when an attribute link is removed, the _deleteLink method runs. The component's _deleteLink method specifies the name of the attribute whose link you want to delete, the source object, and the source attribute for the link.
Note: You could also write SCL code that uses _addLink or _deleteLink to programmatically add or delete an attribute link at run time.
The definitions of your component's attribute metadata determine what happens during attribute linking.
  1. When a source attribute with SendEvent=“Yes” is modified, it sends an “attributeName Changed” event. The event passes an instance of sashelp.classes.AttributeChangedEvent.class that contains information about the event.
  2. The target component has an event handler method with a single argument whose type is object. The argument receives the AttributeChangedEvent instance from the event.
  3. The _onAttributeChange method queries the AttributeChangedEvent object for the name and the value of the attribute that has been changed, as well as for the object identifier of the source object. The _onAttributeChange method then invokes the _setAttributeValue method on the target attribute, which updates the value of the target attribute.
  4. At build time, the _onAttributeChange method sends the “refresh Attributes” event. See Using the Refresh Attributes Event for more information.
For details on the flow of control for the _setAttributeValue method, see Attribute Values and Dot Notation.
If you enable attribute linking, developers who use your components do not have to write any code to establish communication between components.

How the Attribute Changed Event Component Works

The Attribute Changed Event component (sashelp.classes.AttributeChangedEvent.class) provides an object container for passing the information that is used in attribute linking. The information is stored in the following attributes of the Attribute Changed Event component:
attributeName
is the name of the changed attribute.
value
is the value of the changed attribute. This attribute is a complex attribute whose type is sashelp.classes.type.class, which contains the following attributes:
type represents the type of the attribute value (Character, Numeric, List, Object). Based on the value of type, you can query the appropriate “value” attribute.
characterValue stores the character value if type is “Character”.
listValue stores the SCL list if type is “List”.
numericValue stores the numeric value if type is “Numeric”.
objectValue stores the object identifier if type is “Object”.
objectID
is the identifier of the source object whose attribute was changed.
For complete information on the AttributeChangedEvent component, see the “SAS/AF Component Reference” in the SAS/AF online Help.

Example

Sometimes setting an attribute link between two attributes does not provide the complete behavior that your component or application needs. In these situations, you might want to define your own event handler to listen for an “attributeName Changed” event and to perform the desired behavior in the event handler method.
For example, consider a frame with a list box that contains the names of columns in a SAS table. A text entry control is also on the frame. As a user of the frame selects one or more columns in the list box, the text entry control displays a string that contains the list of selected columns, with blank characters separating the column names. The standard attribute linking functionality cannot handle this requirement because of the type mismatch of the attributes that are involved. (The list box stores selected columns as list items in its selectedItems attribute. The text entry control displays the text as a character string in its text attribute.) You must write code to convert the list of items in selectedItems to a concatenated character string that can be displayed in the text entry control.
The following example demonstrates how you can create a subclass of the text entry control to provide such functionality:
  1. Using the Class Editor, create a new class whose parent is sashelp.classes.textentry_c.class and whose description is Smart Text Entry.
  2. Save the class as sasuser.myclasses.SmartTextEntry.class.
  3. Right-click on the Event Handlers node and select New Event Handler. Add an event handler whose Event Generator is “Any Object (*)”. Set the Event Name to selectedItems Changed and the Method Name to onSelectedItemsChanged.
  4. When you are prompted to add the new method, click Yes. In the New Methods dialog box, click the ellipsis (...) button to modify the Signature field. In the Signature dialog box, click the Add button to add a new argument whose type is a specific class name, and then enter sashelp.classes.attributechangedevent. Click OK, and then click OK again to close the New Method dialog box and return to the Class Editor.
  5. Select the Methods node, and then select the new onSelectedItemsChanged method. Right-click and select Source from the pop-up menu, and then add the following SCL code:
    useclass sasuser.myclasses.SmartTextEntry.class;
    onSelectedItemsChanged: public method
       eventObj:sashelp.classes.attributeChangedEvent.class;
       dcl char(500) textstr,
           num i,
           list localList;
       localList = eventObj.value.listValue;
       do i = 1 to listlen(localList);
          textstr = textstr||' '||getitemc(localList,i);
       end;
       text=textstr;     /* set the text attribute */
    endmethod;
    enduseclass;
    Compile and save the SCL entry.
  6. Save the class and close the Class Editor.
You can then use the new Smart Text Entry component in conjunction with a list box control. To create a frame that hosts the Smart Text Entry component:
  1. Create a new frame.
  2. Add the text entry subclass to the Components window by selecting Add Classes from its pop-up menu. Select or enter sasuser.myclasses.SmartTextEntry.class.
    The class named Smart Text Entry appears in the Components window.
  3. Drag a list box control onto the frame. Open the Properties window and set the list box control's selectionMode attribute to “Multiple Selections”.
  4. Drag and drop a Variable List Model component onto the list box to establish a model/view relationship. In the Properties window, set the model's dataSet attribute to a valid SAS table such as sashelp.prdsale.
    The list box should immediately be populated with the column names in the table.
  5. Drag and drop a Smart Text Entry component onto the frame. Resize the component as necessary.
  6. Select Buildthen selectTest to test the frame.
As you make multiple selections from the list box, the text entry control is automatically updated to display a string of selected items. Because the list box control's selectedItems attribute was defined in the class with SendEvent=Yes, the selectedItems Changed event is sent each time the attribute value is changed. The event also includes an instance of the Attribute Changed Event component that contains information about the attribute and its value. The event handler on the Smart Text Entry component retrieves the new value of the Attribute Changed Event component that is passed to the method. The method then loops through the items in the list to create a string of column names that are displayed in the text entry.