Documentation Center

  • Trial Software
  • Product Updates

Dynamic Properties — Adding Properties to an Instance

What Are Dynamic Properties

You can attach properties to objects without defining these properties in the class definition. These dynamic properties are sometimes referred to as instance properties. Use dynamic properties to attach temporary data to objects or assign data that you want to associate with a particular instance of a class, but not all objects of that class.

It is possible for more than one program to define dynamic properties on the same object so you must take care to avoid name conflicts.

Characteristics of Dynamic Properties

Once defined, dynamic properties behave much like class-defined properties:

Defining Dynamic Properties

Any class that is a subclass of the dynamicprops class (which is itself a subclass of the handle class) can define dynamic properties using the addprop method. The syntax is:

P = addprop(H,'PropertyName')

where:

P is an array of meta.DynamicProperty objects

H is an array of handles

PropertyName is the name of the dynamic property you are adding to each object

Naming Dynamic Properties

Use only valid names when naming dynamic properties (see Variable Names). In addition, do not use names that:

  • Are the same as the name of a class method

  • Are the same as the name of a class event

  • Contain a period (.)

Setting Dynamic Property Attributes

Use the meta.DynamicProperty object associated with the dynamic property to set property attributes. For example:

P.Hidden = true;

Remove the dynamic property by deleting its meta.DynamicProperty object:

delete(P);

The property attributes Constant and Abstract have no meaning for dynamic properties and setting the value of these attributes to true has no effect.

Assigning Data to the Dynamic Property

Suppose, you are using a predefined set of GUI widget classes (buttons, sliders, check boxes, etc.) and you want to store the location on a grid of each instance of the widget class. Assume the widget classes are not designed to store location data for your particular layout scheme and you want to avoid creating a map or hash table to maintain this information separately.

Assuming the button class is a subclass of dynamicprops, you could add a dynamic property to store your layout data. Here is a simple class to create a uicontrol button:

classdef button < dynamicprops
   properties
      UiHandle
   end
   methods
      function obj = button(pos)
          if nargin > 0
              if length(pos) == 4
                  obj.UiHandle = uicontrol('Position',pos,...
                'Style','pushbutton');
            else
               error('Improper position')
            end
         end
      end     
   end   
end

Create an instance of the button class, add a dynamic property, and set its value:

b1 = button([20 40 80 20]); % button class uses HG-type position layout
b1.addprop('myCoord'); % Add a dynamic property
b1.myCoord = [2,3];    % Set the property value

You can access the dynamic property just like any other property, but only on the instance on which you defined it:

b1.myCoord 

ans =

     2     3

Responding to Dynamic-Property Events

You can attach listeners to dynamicprops objects to monitor the addition of dynamic properties to the object. You can also monitor the removal of dynamic properties, which occurs when you delete the object.

The dynamicprops class defines two events and inherits one from handle:

  • ObjectBeingDestroyed — Inherited from the handle class.

  • PropertyAdded — Triggered when you add a dynamic property to an object derived from the dynamicprops class.

  • PropertyRemoved — Triggered when you delete the meta.DynamicProperty object associated with the dynamic property.

Suppose you define a button object, as described in the previous section:

b2 = button([20 40 80 20]);

Create a function to attach listeners to the button object, b2, and a listener callback function:

function listenDynoEvent(obj)
   addlistener(obj,'PropertyAdded',@eventPR);
   addlistener(obj,'PropertyRemoved',@eventPR);
   function eventPR(src,evnt)
      mc = metaclass(src);
      fprintf(1,'%s %s \n',mc.Name,'object')
      fprintf(1,'%s %s \n','Event triggered:',evnt.EventName)
   end
end

Triggering the PropertyAdded Event

Add the listeners to the button object, b2. Then, add a dynamic property, myCoord.

% add listeners
listenDynoEvent(b2) 
% add dynamic property and save meta.DynamicProperty object
mp = b2.addprop('myCoord'); 

The listener callback function, eventPR, executes and displays the object class and event name:

button object 
Event triggered: PropertyAdded

Delete the dynamic property by deleting the meta.DynamicProperty object:

delete(mp)
button object 
Event triggered: PropertyRemoved 

Obtain the meta.DynamicProperty object for a dynamic property using the handle findprop method. Use findprop if you do not have the object returned by addprop:

mp = findprop(b2,'myCoord');

Dynamic Properties and Ordinary Property Events

Dynamic properties support property set and get events so you can define listeners for these properties. Listeners are bound to the particular dynamic property for which you define them. Therefore, if you delete a dynamic property, and then create another one with the same name, the listeners do not respond to events generated by the new property, even though the property has the same name as the property for which the event was defined.

Having a listener defined for a deleted dynamic property does not cause an error, but the listener callback is never executed.

Property-Set and Query Events provides more information on how to define listeners for these events.

Defining Property Access Methods for Dynamic Properties

Dynamic properties enable you to add properties to class instances without modifying class definitions. You can also define property set access or get access methods without creating new class methods. See Property Setter and Getter Methods for more on the purpose and techniques of these methods.

    Note:   You can set and get the property values only from within your property access methods. You cannot call another function from the set or get method and attempt to access the property value from that function.

Here are the steps for creating a property access method:

  • Define a function that implements the desired operations you want to perform before the property set or get occurs. These methods must have the following signatures: mySet(obj,val) or val = myGet(obj)

  • Obtain the dynamic property's corresponding meta.DynamicProperty object.

  • Assign a function handle pointing to your set or get property function to the meta.DynamicProperty object's GetMethod or SetMethod property. This function does not need to be a method of the class and you cannot use a naming scheme like set.PropertyName. Instead, use any valid function name.

Suppose you want to create a property set function for the button class dynamic property myCoord created previously. Write the function as follows:

function set_myCoord(obj,val)
   if  ~(length(val) == 2) % require two values
      error('myCoords require two values ')
   end
   obj.myCoord = val; % set property value
end 

Because button is a handle class, the property set function does not need to return the object as an output argument. Assign the value to the property if the value is valid.

Use the handle class method findprop to get the meta.DynamicProperty object:

mb1 = b1.findprop('myCoord');
mb1.SetMethod = @set_myCoord;

The property set function is now called whenever you set this property:

b1.myCoord = [1 2 3] % length must be two
Error using button.set_myCoord
myCoords require two values

Dynamic Properties and ConstructOnLoad

Setting a class's ConstructOnLoad attribute to true causes MATLAB to call the class constructor when loading the class. Dynamic properties are saved and restored when loading an object. If you are creating dynamic properties from the class constructor, you can cause a conflict if you also set the class's ConstructOnLoad attribute to true. Here's the sequence:

  • A saved object saves the names and values of properties, including dynamic properties

  • When loaded, a new object is created and all properties are restored to the values at the time the object was saved

  • Then, the ConstructOnLoad attribute causes a call to the class constructor, which would create another dynamic property with the same name as the loaded property (see The Default Save and Load Process for more on the load sequence)

  • MATLAB prevents a conflict by loading the saved dynamic property, and does not execute addprop when calling the constructor.

If it is necessary for you to use ConstructOnLoad and you add dynamic properties from the class constructor (and want the constructor's call to addprop to be executed at load time) then set the dynamic property's Transient attribute to true. This setting prevents the property from being saved. For example:

classdef (ConstructOnLoad) MyClass < dynamicprops
   function obj = MyClass
      P = addprop(obj,'DynProp');
      P.Transient = true;
      ...
   end
end  
Was this topic helpful?